How to replace a channel with `imports = [...]`?

Hi folks, I am attempting to setup home-manager as a NixOS module. However, I’d prefer to avoid using nix channels, since they are no longer recommended.

The home-manager docs suggest

sudo nix-channel --add https://github.com/nix-community/home-manager/archive/release-23.05.tar.gz home-manager
sudo nix-channel --update

and adding

imports = [ <home-manager/nixos> ];

in /etc/nixos/configuration.nix.

Instead I tried

imports = [ (fetchTarball "https://github.com/nix-community/home-manager/tarball/release-23.05") ];

but that fails with

error: anonymous function at /nix/store/xl229jfp80rpw7jymzaf87wsh4wylg28-source/default.nix:1:1 called with unexpected argument 'config'

       at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:519:8:

          518|       # works.
          519|     in f (args // extraArgs);
             |        ^
          520|

How can I get the same effect using raw imports = [...] without channels?

You’re not using hm’s nixos sub-directory in your fetchTarball but rather the top-level. I believe that’s where the issue lies.

If you don’t wanna use channels, I’d recommend you to use niv or flakes rather than this sort of setup.

1 Like

Thanks @Atemu, using

imports = [ "${fetchTarball "https://github.com/nix-community/home-manager/tarball/release-23.05"}/nixos" ];

did the trick for me

1 Like

Using fetchTarball pointing to a branch without pinning is even worse than channels. With channels, you still control when the source is bumped, even though the pinning is external to your configuration repository. If you just fetch a branch, it will update under your hands every time the cached version expires.

You should use manual pinning:

fetchTarball "https://github.com/nix-community/home-manager/tarball/28535c3a34d79071f2ccb68671971ce0c0984d7e"

Or, if you want to make updating easier, there is niv (see also Sane stable stateless NixOS setup), npins, and Nix’s experimental Flakes feature.

4 Likes