How does home-manager decide what nixpkgs to use in a flake?

I recently migrated my NixOS + home-manager configuration to flakes. I am using home-manager as a NixOS module.

In a flake, when you enable a program/service in home-manager, and do not provide the package option, how does it decide what nixpkgs to pull it from? I don’t think that it calls <nixpkgs> because that would not work in a flake without the --impure option.

Home manager flake points to.nixpkgs-unstable.

You can override this in your system flake.

In a flake HM doesn’t “decide” anything, it just uses whatever you pass as pkgs to the homeManagerConfiguration in the case of standalone.

For the module it depends on how you set home-manager.useGlobalPkgs.

By default HM will just use the same version of nixpkgs that the system is build from (with all overlays and unfree settings, etc). When you haven’t enabled it, it will still use the same nixpkgs, but as a fresh import and you have to do your configuration on your own using nixpkgs.*


Until recently, home-manager standalone would instantiate its nixpkgs input by default, though as I understand it, it now requires that you explicitly specify its pkgs attribute. (which must make the nixpkgs.* options confusingly non-functional in most cases…)

Standalones nixpkgs.* hirarchy works pretty well if you do nixpkgs.legacyPackages.x86_64-linux or whatever system you use.

To my knowledge it only fails to set allowUnfree properly.

Though indeed, if you do some import nixpkgs { … } gymnastics, it will inherit all the configuration from this import and render nixpkgs.* ineffective.

This is why I tend to recite: If you import manually, you are probably doing it wrong.

  • There is no need to import inputs that are a flake, just use their attributes!
  • There is no need to import modules, just add them to the imports or modules lists respectively
  • There is no need to import “packages”, just use callPackage