~/ ~/documents ~/software ~/pictures github (opens in new tab)

Nix Build Purity

Purity is a core idea in Nix, but it’s often talked about in abstract terms. In reality, a pure build is just one where the result depends only on the inputs you’ve declared—nothing sneaky, nothing hidden. That means:

A build isn’t pure just because it works twice in a row. It’s pure if the same declared inputs always give you the same result, no matter where or when you build. Nix enforces this by creating isolated build environments for derivations. A derivation spells out the inputs, the build steps, and the expected outputs. In a proper sandbox, the build only sees what you’ve told it to use.

Impurity usually sneaks in for the sake of convenience. For example, environment variables are ambient state. If your build reads them, it’s depending on something outside the derivation:

buildPhase = ''
  echo ${builtins.getEnv "TOKEN"} > $out
'';

That’s impure—the output now depends on whatever TOKEN was set to at the time. Reading from places like /usr/bin, /etc, /opt, or your home directory breaks reproducibility. These aren’t controlled by the derivation and can change from machine to machine. If your build grabs stuff from the network, it might see different things at different times. Even if the URL is the same, the content might not be. Pure builds fetch sources up front, with hashes to lock them down. Branch names, floating tags, and unpinned dependencies are all moving targets. If you rely on them, you can’t guarantee tomorrow’s build matches today’s.

Purity isn’t just about the code—it’s about how you build. A repo can be perfectly versioned and still build impurely if:

This is where Nix shines: it makes dependencies explicit and keeps the build isolated from the rest of the machine. There are legit reasons to allow impurity:

The problem isn’t impurity itself—it’s letting impurity sneak in and pretend to be reproducibility. If you need impurity, make it obvious, justified, and tightly scoped. Don’t let it slip in by accident.

When someone says a build is reproducible, ask:

Reproducible from which inputs, under what constraints, and with what ambient state excluded?

If the answer is fuzzy, the build probably isn’t as reproducible as claimed. Purity in practice means drawing a hard line around what can affect your build. Nix gives you the tools to do that. The rest is up to you.


See also: