Farid Zakaria

4 min read

nixpkgs-multiverse is audacitymaxxing


Every package manager on earth picks one version for you. Nixpkgs picked one too. It never had to.

I shared nixpkgs-multiverse recently: one flake input that hands you every version of every package that ever shipped in Nixpkgs.

I love how unbelievable audacious Nix lets me be, audacitymaxxing.

As of this writing, you have access to 31,783 packages and 304,484 distinct package version pairs pulled from 1,537 revisions. 🤯

The fact most distributions only give you one version of each package is not a bug. It is often considered a feature: a single self-consistent set of software that boots and runs together. It falls directly out of a shared global filesystem, the filesystem hierarchy standard (FHS), like /usr, /lib and /etc.

The purpose and existence of Nix is to eschew from that convention and allow multiple versions of the same package to coexist. Nixpkgs is a distribution built on that capability, and yet, it has been doing the same thing as every other distribution: picking one version of everything.

nixpkgs-multiverse only supports, at the moment, top-level attributes that are packages but already the sheer volume of installable software dwarfs nixpkgs-unstable.11The data was fetched from the Repology repository size map. 

1980-01-01T00:00:00+00:00 image/svg+xml Matplotlib v3.10.5, https://matplotlib.org/

Nix’s answer to the FHS was audacious in 2003 and is still audacious now. A package lives at /nix/store/<hash>-python3-3.12.10, where the hash is derived from every input that went into building it: the intensional model.

How audacious are we? How about 246 distinct CPython versions, from 2.6.8 forward, all installable side by side, all built and cached, all addressable by version number instead of commit hash.22The data for other distributions was fetched from Repology

1980-01-01T00:00:00+00:00 image/svg+xml Matplotlib v3.10.5, https://matplotlib.org/

To re-iterate, these are distinct versions of CPython, including their transitive dependencies. There is no glibc or openssl or zlib that is shared between them.33Unless they happen to dedupe due to their hash.  They work just as reliably as when they were first released, and they are all still installable today and can be substituted from the cache.

People want to pin to a version. Upgrading software can be disruptive, and some people have to stay on a particular version but that should not impede the rest of the world from moving forward.

The nixpkgs-multiverse helped solve one of the oldest devenv.sh issues, cachix/devenv#16, the desire to pin a specific package.

“It is not really practical to pin a separate version of nixpkgs for every different version of a tool needed in a dev environment. Normally we have at least 20-30 different tools all with a specific pinned version that we would want to specify.” – itpropro

The issue, “Pinning a specific package”, was opened on 2022-11-10 and is now closed. devenv now documents the multiverse as the solution. 💪

The audacity of the multiverse is not technical. Nix took care of that. There is no clever trick in here; it’s 5 MB of JSON, about 200 lines of Nix and a builtins.fetchTree behind a memo table.

The audacity is in the premise.

§Odds and ends

Two smaller things landed that I like and which was driven by feedback from the community.

A soak period. daysBehind gives you the whole of nixos-unstable as it stood N days before an anchor, a cooldown window, in the spirit of Determinate Systems’ cooldowns, except the anchor can be any selector at takes.

nix-repl> (mv.daysBehind "tip" 7).hello.version
"2.12.3"
nix-repl> (mv.daysBehind "tip" 365).hello.version
"2.12.2"

Provenance. Every package set carries where it came from, so a pkgs you were handed can be interrogated rather than guessed at.

nix-repl> (mv.at "26.05").multiverse
{ build = 7376; date = "2026-08-09"; name = "nixos-26.05.7376.fcb8fcd6bf2d";
  release = "26.05"; rev = "fcb8fcd6bf2d0adecae5bd491afaaaf8311b758d"; }

nix-repl> (mv.at "2022-03-15").multiverse
{ date = "2022-03-14"; label = "2022-03-14-73ad5f9e147c";
  rev = "73ad5f9e147c0d2a2061f1d4bd91e05078dc0b58"; }