ZLS cannot find import file on NixOS

I have a ZIG project on NixOS where I use a nix-shell to add dependencies using pkg-config. Everything works except ZLS cannot find the lib.
(I’m using ZED with the ZIG extension and ZLS installed on the base system)

I add the lib in build.zig using

exe.linkSystemLibrary("dbus-1");

nix.shell is

let
  pkgs = import <nixpkgs> {};
in
  pkgs.mkShell {
    buildInputs = with pkgs; [
        dbus
    ];
    nativeBuildInputs = with pkgs; [
        pkg-config
    ];
  }

(I’ve ignored it until it suddenly started to bum me and the topic about ZLS not finding raylib didn’t help me out)

I apologize for my ignorance on nix.shell as I am a flake user, but I’ll try to help out anyway.

Personally I would highly recommend avoiding global installs as much as possible, as it makes picking up a project 2 or 3 years down the line harder, and instead using flakes + nix-direnv, which automatically loads the packages you need for a particular project whenever you cd into its directory.

You can see an example of this in my Advent of Code repo, but I will also post a minimal flake.nix that should work for your use case.

{
  description = "A basic Zig flake";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
    nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable";

    flake-parts.url = "github:hercules-ci/flake-parts";
  };

  outputs =
    inputs@{ self
    , flake-parts
    , nixpkgs
    , nixpkgs-unstable
    }:
    flake-parts.lib.mkFlake { inherit inputs; } {
      imports = [ ];
      systems = [ "x86_64-linux" ]; # Adjust according to your needs

      perSystem =
        { pkgs, system, inputs', ... }:
        {
          # Allow unstable and Unfree packages
          _module.args.pkgs = import nixpkgs {
            inherit system;
            config.allowUnfree = true;

            overlays = [
              (final: prev: { unstable = inputs'.nixpkgs-unstable.legacyPackages; })
            ];
          };

          devShells.default = pkgs.mkShell
            {
              buildInputs = with pkgs; [
                unstable.zls
                unstable.zig

                # Zed may or may not work if installed globally,
                # With a gloabl VSCode install you can get the direnv extension 
                # to auto load your dev shell.
                #
                # commandline editors like neovim and helix automatically
                # work ofc with direnv
                zed-editor
              ];
            };
          };
        };
    };
}

I realize this probably isn’t the answer you’re looking for, but I would argue that the power of nix is its reproducability, and the more global (system level) state you have, the more you poison that reproducability. Even though all my projects use this setup, I still have been shot in the foot with a global nushell install as my default shell, which can result in different shell versions being used depending on how I run the script :sweat_smile:

Another benefit of doing things this way is that if you manage to bundle your code as a flake pkg, (which can be a major PITA, I know), and you experience build issues you need help with, any (flakes enabled) nix user can easily check if your build works by running nix run 'github:user/repo' on their machine.

Sorry if this is all obvious and I’m being a jerk here.

I did consider switching to a flake for my little shell but really saw no point in it for this silly little project (and as i understand it the shell follows my main system flake.lock which at least for now is enough for me ^-^)

Edit:
Things I’ve tried additionally tried now

  • remove zls from main system putting it into the shell (and launching zed from shell)
  • replacing the zig extensions with the official config which did not work at all (just didn’t do anything and logs were empty)
  • remove zls completely letting zed download the lsp by itself