Nix expressions can return values of any type. The build workflow discussed here begins only when evaluation produces a derivation and the build descriptions for its dependencies.
What is a derivation?#
A derivation is a core Nix primitive. It is a text file with a .drv suffix that describes how to build a package:
- Inputs: source code, dependency packages, and build scripts.
- Build environment: the build platform, builder, and environment parameters. Sandbox isolation depends on the platform and Nix settings; not every build is guaranteed to be fully isolated.
- Outputs: the binaries, libraries, and documentation produced by the build.
Breaking down the build process#
- Evaluation: The Nix interpreter runs your
.nixcode and generates.drvfiles. - Realisation: Nix checks for existing outputs, preferring to download substitutes from trusted caches; otherwise, it builds according to the
.drvfile. The traditionalnix-instantiatecommand evaluates expressions to produce build descriptions; it does not run the builds. - Storage: Build results are stored in
/nix/store.
Immutability, input addressing, and content addressing#
- Where the hash prefix comes from: Common derivation outputs are input-addressed: their paths are determined by the build description, dependencies, and related inputs. The prefix should not simply be described as a hash of the output contents. Fixed-output and content-addressed derivations use different path rules and need to be distinguished.
- The magic of caching: If the hash of what you are building already exists in a binary cache such as
cache.nixos.org, Nix can download the corresponding outputs from a trusted substituter and avoid building locally.
Why does your configuration go into /nix/store too?#
When you run nixos-rebuild switch, module evaluation generates build descriptions for the system closure. The outputs include activation scripts, service definitions, generated configuration, and their dependencies. Activation then connects the generated files to locations such as /etc. Your source configuration may enter the store as part of the Flake source, but rolling back does not restore the source files in your working directory.
- This is why you can roll back the system: the old configuration files are also in
/nix/store, and switching back just changes the targets of the symbolic links again.
A developer's view: nix-shell#
nix-shell provides a derivation's build dependencies and corresponding environment. It normally does not run the target package's final builder, though it may still build or download dependencies. nix develop is intended for Flake development environments, while nix shell primarily adds programs provided by packages to PATH. The three are not fully equivalent.
Summary: the three stages of Nix#
- Describe: Write attribute sets in
.nixfiles. - Derive: Generate a
.drvbuild plan. - Produce: Create read-only directories in
/nix/store.
References & further reading
Adapted from technical notes. Examples use generic names.