I feel like NIX_PATH creates more issues than it fixes

Two issues from my point of view:

  1. NIX_PATH gets cached since applications do not re-source /etc/set-environment due to this if statement located in /etc/profile
if [ -z "$__NIXOS_SET_ENVIRONMENT_DONE" ]; then
    . /nix/store/sm7s4dlgji6p2gzigh5xalxwly372ijg-set-environment
  1. PAM environment depends on NIX_PATH (I am not sure why :/) which means that it gets rebuilt each time NIX_PATH changes, and in my case it happens on each rebuild:
❯ echo $NIX_PATH | sed 's/:/\n/g'

Admittedly, I am planning on changing the implementation of the use cases I am handling here, so I guess it’s not much of an issue.

An alternative implementation of NIX_PATH:
If possible - should get directly passed to applications that require it via config.nix.nixPath - otherwise file is read when required from /etc/nix which contains its definition (similar to the registry)

Could it be that I am missing some use cases?

Based on what you describe here you are probably better off using flakes already.


I am using flakes, but as I said - I will change my flakes implementation at least partially. But then again, it’s not like flakes deprecate NIX_PATH

Edit: now that I think about it, in the case when using flakes (nixUnstable) - the only use case is when using nix repl (assuming you don’t have any automagic script for it). Cant think of any other “legit” cases

Better use something like this:

  environment.etc."channels/nixpkgs".source = nixpkgs.outPath;
  environment.etc."channels/home-manager".source = home-manager.outPath;
  nixPath = [

where nixpkgs and home-manager are flake inputs.

The entries in /etc will be relinked during activation and your applications will be able to see the updated channels.

1 Like

I don’t think that /etc is the correct place to place em but yeah, I was thinking about something similar.

I created this post, not in search of a workaround, but to create a discussion if we actually can consider getting rid of the NIX_PATH environment variable. I feel like this would be a quite an appropriate addition to Nix 3.0

An empty NIX_PATH works also with nix repl. Just use builtins.getFlake instead of :l or import.

$ NIX_PATH= nix repl
Welcome to Nix version 2.4pre20210308_1c0e3e4. Type :? for help.

nix-repl> :l <nixpkgs>
error: file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I)

nix-repl> flake = builtins.getFlake "/etc/nixos"

nix-repl> flake.inputs.nixpkgs.legacyPackages.x86_64-linux.hello
«derivation /nix/store/70vmydmb7hv290k7v459qlcqmnykpzxq-hello-2.10.drv»

I’ve actually used an empty NIX_PATH for a couple of days, but I’ve found myself using some legacy utilities like nix-shell once in a while and other tooling like nixpkgs-review does not work with flakes yet. This inconvenience wasn’t worth it for me and I went back to using NIX_PATH with flake inputs linked into /etc.

1 Like

A few people and I discussed this on Discord a earlier. My side:

My <nixpkgs> is literally now just a wrapper around builtins.getFlake, so that nix-shell -p still works. It’s also a bit easier to use :l <nixpkgs> than :a (builtins.getFlake "flake:default").outputs.legacyPackages.${builtins.currentSystem}. If we can get nix-shell -p and nix repl to behave better with flakes, I think I can pretty much do without NIX_PATH.


@dramforever how do you accomplish this?

1 Like