What is the origins of pkgs?

Disclaimer: another noob question that might be “mind bending” to some out there.

In flake.nix you can define:
pkgs = import nixpkgs { inherit system; };
And, you can pass this value over to for example home.nix. Which makes sense.

However, you do not need to define pkgs in flake.nix at all. You can still define it as an input to home.nix, and it just works (example: flake.nix and home.nix).

Where does the pkgs value automatically come from, when you do not define it yourself?

I have looked at the Nixpkgs Parameters in the guide. But, I can not see this explained there. Can someone point me to a location in a manual where the origins of pkgs is explained?

In a nutshell, from inputs.nixpkgs, as may ultimately be somewhat unsurprising.

nixpkgs.lib.nixosSystem (where nixpkgs is taken from your args to the outputs function) will evaluate the NixOS module system. It in turn does the import nixpkgs { } thing for you, albeit subtly differently.

That then eventually adds the home-manager module to your module system, which takes the very pkgs defined by nixosSystem as an argument (from the module arguments, like your configuration.nix), and passes it to the home-manager module system.

In other words, this is an anti-pattern, and results in you evaluating nixpkgs multiple times:

There are some edge cases where doing that is semi-necessary because flakes can’t take arguments, so e.g. allowing unfree packages without nixpkgs.config is impossible, but this is only a problem when you don’t use the system nixpkgs for an unfree package, and even then there is nixpkgs-unfree as a crutch to fix that.

If you use pkgs inside flake.nix, it’s better to do:

pkgs = nixpkgs.legacyPackages.${system};

And you should still never pass it to nixpkgs.lib.nixosSystem, or anywhere else in your actual configuration, unless you really know what you’re doing.

I don’t think the manuals explain any of this because these are deep, eldritch details of the NixOS module system.


@TLATER Thanks a lot for taking the time to explain this!

1 Like