Nix channels: aliases, naming, and package availability

What is the significance of nix channels’ aliases on nix-shells? I just ran into a situation where I was trying to install rust-analyzer, but was unable to do so until I created another channel alias called nixpkgs.

To be clear, I originally had this output from nix-channel --list

nixos https://nixos.org/channels/nixos-unstable

Running nix search rust-analyzer yielded the following (among other nixos... results):

nixos.rust-analyzer (rust-analyzer-unstable)

So I knew the package was there, but I was still told that the attribute didn’t exist.

When I added a new alias for the same channel, suddenly everything worked. The output of nix-channel --list looks like this now:

nixos https://nixos.org/channels/nixos-unstable
nixpkgs https://nixos.org/channels/nixos-unstable

Why does it matter what alias is used? I’m sure I’m missing something, but I haven’t been able to find any info on this.

And while we’re at it, what’s the difference between the root channels (sudo nix-channel --list) and the user level ones? I use the latest stable for nixos for root, but unstable for the user. Is this good? Bad? Normal? Is there a guide for how to do this somewhere?

Thanks!

2 Likes

I’m also quite confused about this.

1 Like

The aliases are used between the <> brackets in Nix code, like <nixpkgs> or <nixos> – that’s a valid Nix expression in code which is why you see things like import <nixpkgs> {}. I’m assuming you’re using nix-env to install packages, so what you’d need to do is nix-env -f '<nixos>' -iA rust-analyzer. The -A is important, it says “dump all the fields in nixpkgs to my top-level scope” so you can simply refer to it as rust-analyzer.

By default nix-env uses <nixpkgs>, or specifically a partial set of it without things like haskellPackages because they slow things down and you explicitly need use -f '<nixpkgs>' (or <nixos>) to force evaluation of the whole thing, but unless your package is a specific language’s library or tool, it’s likely outside of these languagePackages attributes.

For root and user channels, your system (nixos-rebuild) uses the root ones, and your user uses the user ones through nix-env, nix repl, nix-build, nix-shell, and so forth. So you’d upgrade the packages your system has available if you did sudo nix-channel --update.

Also instead of nix search you can use nix repl '<nixpkgs>' to see what <nixpkgs> contains. <> expressions also support sub-directories, so nix repl '<nixpkgs/nixos>' evaluates the NixOS specific parts of nixpkgs (i.e. default.nix in nixpkgs/nixos), that your system uses, albeit – as mentioned – from the channel defined by root.

Edit: sorry just noticed you mentioned nix-shell, yeah, it uses <nixpkgs> by default. You can override it with e.g. nix-shell -I nixpkgs=/home/user/nixpkgs. Instead of a path you can also provide an URL to a tarball: nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/tarball/master -p hello

If you do echo $NIX_PATH you’ll see something like nixpkgs=foo nixos-config=bar and those are indeed available within <> brackets.

2 Likes

@Shou Thanks for the detailed answer. That explains a lot! I think I originally had nixpkgs, but changed it to nixos because something wasn’t working as expected, but I can’t remember what now. I’ll see if I can find out.

Thanks also for the clarification on root vs user level channels. This was very much in line with my understanding, so I’m glad to see that I at least got something right, hah.

About the nix repl: is there a guide on how to do find packages or use it for anything useful? I’ve never used it because I’m not sure what I’d use it for.

As for nix-shell and shell.nix files: I usually see files that start with:

{ pkgs ? import <nixpkgs> {} }:

If that was changed to

{ pkgs ? import <foo> {} }:

would it have made it use the foo channel instead?

1 Like

Actually, the angle bracket syntax is Nix feature unrelated to channels. It only happens that a directory containing channel symlinks is listed in the NIX_PATH environment variable by default.

Yup, as long as you have /nix/var/nix/profiles/per-user/root/channels in your $NIX_PATH (or $HOME/.nix-defexpr/channels for the user channels).

2 Likes