Troubles adopting the new Nix

I just recently found the time to finally try out what’s been cooking in nixUnstable and need to re-learn doing the thing I usually do when working with Nix.

One of these is overriding nixpkgs with a local checkout.

How can I do the equivalent of e.g. nix run nixpkgs.hello -I nixpkgs=~/Projects/nixpkgs now?

The new command is nix shell and you now use nixpkgs#hello instead of referencing nixpkgs from the NIX_PATH but how can I override what the nixpkgs flake points to in an ad-hoc manner?

I know the registry exists but that’s more of an alternative for channel management and I don’t want to make any permanent changes.

You can use /path/to/nixpkgs#hello but that dumps /path/to/nixpkgs into the nix store every time you try to do anything with it which is entirely unusable as every bash completion now waits for the nix-daemon to dump /path/to/nixpkgs into the nix store again. I just want to eval the current state of the flake at /path/to/nixpkgs.

Speaking of completions, another issue I had was that nix-bash-completions are broken for nix commands. Nix now has it’s own bash completions but unfortunately, there does not seem to be a bash completion for e.g. nix build -f /path/to/nixpkgs hell<TAB> or the old nix- tools.
Is there a way to use nix‘s completion for the new nix commands and nix-bash-completions’ for the old ones?

Currently, I manage my system-wide nixpkgs rev with a worktree of my local Nixpkgs checkout of my Nixpkgs fork where I merge and cherry pick things before they make it into master.
I usually make changes in my nixpkgs checkout’s master and then use a bash alias to update the worktree to that rev once I’m done. How can I translate that into the new way?
I could use github:Atemu/nixpkgs but I don’t want to have to push my changes to GH every time I make some experimental change and want it to be in-effect for every Nix invocation system-wide.

I think it might still copy to the store, but you should be able to use --override-input to temporarily override the flake lock file and use a different value for an input.

That is indeed the only option using the new interface.

If you do not want that the full flake is copied into the store, do not use the flake.

For nixpkgs you can still use the 1.x style interface with the dash. nix-build, nix-shell, etc.

But what if I want to hack on a flake? Does it really have to dump the entire directory into the nix store every time I try to evaluate anything in a local flake?

Yes. That is how it currently works.

1 Like

For what it’s worth, while I’ve adjusted to this workflow, I think it’s a very reasonable ask. I’ve noticed it can be a burden, especially on systems with slower disks, for sure.


I think that nixpkgs#hello takes by default the nixpkgs from the registry, but I may be wrong. I pin the system nixpkgs by setting it nix.registry. You can then pin it as a user with the nix registry pin subcommand.

as a substitute of nix-shell I’m actually using nix develop, as suggested by the nixos wiki page on flakes. I didn’t go relly any deeper yet into the reason for the two commands, but it as an --override-flake option and a bunch of others.

This is a bit OT, but the difference is that nix shell nixpkgs#hello will bring hello into the PATH, whereas nix develop nixpkgs#hello will bring the nativeBuildInputs of hello into the PATH (e.g. gcc, gnumake)

1 Like