Reduce dependency duplication by syncing flake locks with your system

Nix flakes are amazing tool for software development and distribution which I really enjoy using. The main advantages they provide to my workflow are:

These features in addition to the broader Nix(OS) benefit of being able to have arbitrarily many different (and recent) versions of the same package (especially libraries) installed side by side on the same system give me freedoms hard to achieve with other Linux systems (without installing Nix).

That is not to say that Nix(OS) doesn’t come with some compromises however, such as the lacking out-of-the-box compatibility with many commercial software products that are not directly available via nixpkgs.

When it comes to the use of flakes for software development, one issue of having the exact commit of dependencies locked is the almost unavoidable duplication of tons of libraries in the nix store, leading to increased disk usage and large downloads. While it’s a price worth paying to guarantee successful deployment and compatibility, it’s also a burden worth avoiding during development.

For this reason I tend to use the traditional shell.nix approach for projects that don’t need to be distributed/deployed and therefore don’t benefit as much from using flakes.

For the other cases, I used to manually lock flake inputs (mainly nixpkgs) of new projects to the exact same version that I was using for my system at the time. A similar technique and some scripts were previously discussed on the NixOS discourse. In a stroke of motivation I now decided to automate this process using a little script of my own. I am calling it gnx-syslock (gnx due to my goarnix system flake name).

See gnx-syslock.bash on GitHub Gist.

The script is typically run from the directory of the project flake and by default syncs the version of the nixpkgs input to that of the corresponding input of your system flake. This only works reliably if the two flake inputs have the same source value in the flake.nix file, e.g. nixpkgs/nixos-26.05. If they differ, the script will warn you about it.

Typical usage examples:

nix flake new project-dir
cd project-dir
# edit flake.nix to set nixpkgs to same target version as system
gnx-syslock # this then makes sure they are locked to the exact same revision

# other inputs can be synced instead (this sync's the flake's 'abcd' to the systems 'efgh')
gnx-syslock abcd=efgh

# system and project flake files can be overridden
gnx-syslock -t /path/to/project -s /path/to/system/flake

# warning about target version mismatch can be ignored (but not recommended)
gnx-syslock -i

To use it yourself, just update the SYSFLAKE to the directory of your system flake and change the default input mapping to however your main nixpkgs input is called (e.g. you may prefer using unstable for project flakes).

Feel free to adapt this to your needs or suggest changes on GitHub.

Side note: This is one of those small projects just not worth creating a flake for in my opinion, although it would allow convenient execution by others. Instead, I just added it to the lis of NixOS system utility scripts that I keep in my system flake.