After the derivation is built, what happens to files in $out?

I’m trying to understand the results of installing a nix package. Here’s what I have pieced together so far. I would appreciate any help in filling in the gaps or correcting my mistakes. Or perhaps you can point to some existing documentation on this.

Any files the nix expression for the package creates in $out will be in /nix/store/blahblahblahblahblahblahblayblah-thepackage-version/. For simplicity, I’m going to refer to this directory as $out in the comments below.

Once a package is available…


Any files in $out/bin will be on your path ($PATH), so you can run the executables. This happens automatically, the nix expression for the package doesn’t need to do anything special to make this happen. The way this happens depends on how you made it available.

If you installed it in NixOS (by adding environment.systemPackages), links to those files are created in /run/current-system/sw/bin, which is in $PATH.

If you installed it using nix-env -i, links to those files are created in ~/.nix-profile/bin, which is in $PATH.

If you launched a shell using nix-shell -p, $out/bin is added to $PATH.


Any files under $out/share will appear in the suitable places in the system. The way this happens depends on how you made it available. Q: This happens automatically, right? The nix expression for the package doesn’t need to do anything special to make this happen?

If you installed it in NixOS, the directory under /run/current-system/sw/share will have links to all those files, mirroring the directory structure.

  • The output of manpath will include /run/current-system/sw/share/man, so man pages work.
  • $INFOPATH includes /run/current-system/sw/share/info, so info works.

If you installed it using nix-env -i, the directory tree under ~/.nix-profile/share will have links to all those files, mirroring the directory structure.

  • The output of manpath will include ~/.nix-profile/share/man, so man pages work.
  • $INFOPATH will include ~/.nix-profile/share/info, so info works.

If you launched a shell using nix-shell -p,

  • $out/share/man is added to the manpath, so man pages work.
  • No new entries are added to $INFOPATH, so I don’t know why info works, but it does.

Any files under $out/etc will appear in the suitable places in the system. The way this happens depends on how you made it available. Q: Does this happen automatically?

If you installed it in NixOS, /run/current-system/sw/etc/xdg will have links to everything in $out/etc.
Since /run/current-system/sw/etc/xdg is in $XDG_CONFIG_DIRS, if the package follows the XDG Base Directory Specification, it can find those configuration files.

If you installed it using nix-env -i, then what?

If you launched a shell using nix-shell -p, ~/.nix-profile/etc will have links to everything in $out/etc. Since ~/.nix-profile/etc is in $XDG_CONFIG_DIRS, if the package follows the XDG Base Directory Specification, it can find those configuration files.


Q: Are there any other things that happen automatically to files under $out?

1 Like

Yes. To be more precise, a derivation is fundamentally a way of creating a nix store object. So other than what it puts in $out (and other outputs if it has more than one), a derivation has no way to affect anything outside.

On nixos, yes. That’s the only place it really makes much sense.

Theoretically, almost anything. It’s all a matter of how nixos and nix-env and home-manager and nix-shell are programmed to use the filestructure of a derivation’s output.

In practice, things are pretty well standardized. Roughly speaking, it’s like the FHS but with usr/ stripped off the front of anything that uses it, and sbin replaced with bin.

1 Like

Ah, that’s very helpful! Here’s a description of FHS if anyone needs it.

1 Like