Understanding the differt method of installing applications


Just wrapping my head around this but can someone either explain or point to a place in the manual that can explain the difference between environment.systemPackages vs programs? e.g. why is fish shell enabled using programs.fish.enable = true; and not adding it to the systemPackages list?

Also I believe home manager also has another method of specifying packages using home.packages? Is that related to either of the native ones?

Edit: also just learned there is another way users.users.<name>.packages but this is explained on Nix search: " The set of packages that should be made available to the user. This is in contrast to environment.systemPackages, which adds packages to all users."


Installing via environment.systemPackages makes the program available in your system profile. This means that the program components, usually mainly the binaries, are being linked to /run/current-system/sw/bin so that they can easily be used. This may also extend to certain artifacts (e.g. manpages) put into the correct place. Nothing else is being done. If you install a server-service, there will be no configuration done, not even a systemd-unit being created.

If you use something like program.fish.enable = true;, often also called services.*, you will use the NixOS module for the program/service. Usually, there is more options than just enable and it is used to generate configuration files, systemd units, etc. For the concrete example of fish, adding it to environment.systemPackages is even something that is being done, because you usally want your shell on the PATH. But of course, the module does a lot more. How much is being done exactly depends on the module and the amount of work that was put into it. This is usually what you want to do, unless you have a good reason to do differently. Also, when using NixOS modules, things are usually system-wide.

This is the main difference when using these options from home-manager. The HM-modules are scoped to the user for which the HM profile is being setup. So instead of installing global services and configuration files to /etc, HM modules will setup systemd user services or create config files under /home/<user>. It’s a great way to manage your /home and make sure it’s consistent on many machines. It’s also available on Non-NixOS systems, if that is relevant to you.