Since nix version 2.26, the user and system registries are ignored by nix flake commands (changelog). The rationale behind that change is to avoid having local paths creep into flake lockfiles, which makes sense. However, this also means that my now 40-ish projects all defining a devshell point to wildly different versions of nixpkgs depending on when I last opened them / updated their inputs (I have like 5 different version of golang and clang in different projects). This also causes a lot of rebuilds, downloads, caching, etc…
I understand that flakes used for “wide” projects with many different people should have a flake.lock pinning versions so that everything is reproducible between different developpers, but for most of these I am sole developper using nix (sometimes there are two of us) and I use these devshells to avoid having to install the different tools needed for all these projects globally.
I am using nix-direnv, and previously something like use flake . --override-input nixpkgs nixpkgs would work just fine, but due to the change mentioned above it does not work anymore (and also, this is mentioned nowhere except in that single changelog, and it took me several hours to figure out why this behaved differently from before - I hope this post also helps other people figure it out if they bump into this).
The nix manpage suggests using the --override-flake flag to override registries during local evaluation, but it takes a resolved-ref and would require the actual path to be hard-coded in the .envrc file.
How do you guys deal with many different development projects, using similar stacks, to avoid having a different version of nixpkgs in each one ? Has the change in behavior since 2.26 broken other people’s workflows too ?
It “works” but not in the sense of doing what it previously did: what happens is that your nixpkgs flake input is overriden to point to the flake:nixpkgs entry of the global registry, not the system registry (that 8d6cdc commit was the latest unstable for about when I wrote this post).
So that means that over a large number of projects, especially if you come back to something you haven’t opened in a while and your system nixpkgs version has moved, you spend several minutes waiting for a copy of nixpkgs to be downloaded and copied to the store ? I am running on a 2019 MBP for work and the “unpacking” and “copying … to the store” phases when I set to a reference of nixpkgs that isn’t already present on my system takes 7-10 minutes. This means that for projects I am working on daily everything is good, but coming back to projects untouched since about a month or so usually implies a coffee break - a good thing, but not when forced ^^’
You say you update dependencies in a “controlled” fashion. What exact strategy do you use for this ? Do you have a hash of nixpkgs that you keep most of your projects at ? How does that compound with teamwork ? Do you have a way of aligning the versions across projects for a team of devs ?
Just to be clear, I’m not trying to complain or anything, just looking for advice on best practices to have a more usable dev experience. Waiting so long upon coming back to a project is… a pain, really, and I feel like there is probably a better way I just don’t know of.
I ran that on a system without a local entry, my bad…
So lets test it again, on the other machine with actual local entries…
$ system flake:nixpkgs path:/nix/store/syvnmj3hhckkbncm94kfkbl76qsdqqj3-source?lastModified=1749285348&narHash=sha256-frdhQvPbmDYaScPFiCnfdh3B/Vh81Uuoo0w5TkWmmjU%3D&rev=3e3afe5174c561dee0df6f2c2b2236990146329f
global flake:nixpkgs github:NixOS/nixpkgs/nixpkgs-unstable
$ nix print-dev-env . --override-input nixpkgs flake:nixpkgs
warning: not writing modified lock file of flake 'git+file:///home/nmelzer/Projects/astro/nobbz_dev':
• Updated input 'nixpkgs':
'github:nixos/nixpkgs/3866ad91cfc172f08a6839def503d8fc2923c603?narHash=sha256-oS0Gxh63Df8b8r04lqEYDDLKhHIrVr9/JLOn2bn8JaI%3D' (2025-05-29)
→ 'path:/nix/store/syvnmj3hhckkbncm94kfkbl76qsdqqj3-source?lastModified=1749285348&narHash=sha256-frdhQvPbmDYaScPFiCnfdh3B/Vh81Uuoo0w5TkWmmjU%3D&rev=3e3afe5174c561dee0df6f2c2b2236990146329f' (2025-06-07)
It works…
Yes. This way I am sure, that the unintended toolchain update does not introduce unintended problems.
I want to consciously update toolchains and dependencies, ensuring no random system update introducing troubles.
This is a feature of nix, and the reason why we use it!
no
Depends on the project.
If the project is controlled by me, I assume everyone is using the same shell as I am, and therefore uses the same tools as I am. The flake-lock is then updated irregularly by me.
In teams where someone else controls the flake, I trust them to update on their behalf.
In teams where I just have my own flake, while the remainder of the team doesnt use nix at all, I update the flake when I feel it fits. But I generally avoid doing so, unless there has been something in the project that requires updating, like changing the toolchain version by the team.
Thats why I have nix-direnv configured to keep gc-roots. And I semi-regularly delete those roots, that I consider obselete, as I am not seeing myself contributing to the repo again soon.
What version of nix are you running ? I can’t seem to reproduce your example:
$ nix --version
nix (Nix) 2.28.3
$ nix registry list | grep nixpkgs
system flake:nixpkgs path:/nix/store/93qjm0b4an8681fh0d9r1lz29nn20hh1-source
global flake:nixpkgs github:NixOS/nixpkgs/nixpkgs-unstable