Nix Fundamentals Reference
A comprehensive guide to Nix’s core concepts: store paths, derivations, evaluation model, and build process.
Table of Contents
Section titled “Table of Contents”- Nix Store Paths
- Derivations
- The Nix Store
- Evaluation Model
- Build Process
- Binary Caches
- Garbage Collection
- Fixed-Output Derivations
- Quick Reference
- Related Documentation
Nix Store Paths
Section titled “Nix Store Paths”Why Every Path Has a Hash
Section titled “Why Every Path Has a Hash”Every path in /nix/store
starts with a unique hash:
/nix/store/1v3d2qj7k6vvkr7mprqnlk4p4yyk2r7d-python3-3.10.12 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 32-character base-32 hash
Hash Components
Section titled “Hash Components”What it is | Key points |
---|---|
A deterministic ID | The 32-character string is a base-32 encoding of the first 160 bits of a SHA-256 hash (older Nix once used MD5, which is why you sometimes still hear that). |
What gets hashed | Nix hashes a derivation file (.drv) that records: • The exact build script • All compile flags and environment variables • Absolute paths of every input in /nix/store This recipe is serialized to a Nix archive (NAR) and then hashed. |
Why 160 bits, not the full 256 | 160 bits keeps paths short enough to stay under Unix’s 255-byte filename limit while still leaving the chance of a collision astronomically low. |
What it guarantees | If any dependency, flag, or patch changes, the hash changes, so the output gets a new, unique path. That means: • Builds are pure (no accidental reuse of impure results) • Multiple versions can coexist side-by-side • Nix can treat packages like immutable content-addressed blobs for caching and binary substituters. |
Practical Takeaway
Section titled “Practical Takeaway”You never have to compute or remember these hashes. Nix does it so that:
- Every build is reproducible and referentially transparent
- The package manager can tell with one look at the path exactly which build recipe produced the files
Think of the hash as the package’s fingerprint: change even a single bit of the recipe or its inputs and you get an entirely new fingerprint, guaranteeing there is no accidental overlap in the store.
Derivations
Section titled “Derivations”What is a Derivation?
Section titled “What is a Derivation?”A derivation (.drv file) is a build recipe that Nix uses to produce store paths. It’s a pure description of:
- Inputs: All dependencies (other store paths)
- Builder: The program that performs the build
- Environment: All environment variables
- Outputs: What store paths will be produced
Derivation File Format
Section titled “Derivation File Format”Derivations are stored in /nix/store
with a .drv
extension:
/nix/store/abc123...-hello-2.10.drv
They’re actually ATerm files (a tree-based data format), but you can inspect them:
# View derivationnix derivation show /nix/store/...-hello-2.10.drv
# Or for a packagenix derivation show nixpkgs#hello
Example Derivation Structure
Section titled “Example Derivation Structure”{ "/nix/store/abc123...-hello-2.10.drv": { "outputs": { "out": { "path": "/nix/store/xyz789...-hello-2.10" } }, "inputSrcs": [ "/nix/store/...-hello-2.10.tar.gz" ], "inputDrvs": { "/nix/store/...-bash-5.1.drv": ["out"], "/nix/store/...-gcc-11.3.0.drv": ["out"] }, "system": "x86_64-linux", "builder": "/nix/store/...-bash-5.1/bin/bash", "args": ["-e", "/nix/store/...-builder.sh"], "env": { "name": "hello-2.10", "src": "/nix/store/...-hello-2.10.tar.gz", "buildInputs": "..." } }}
Key Derivation Properties
Section titled “Key Derivation Properties”- Inputs determine output - Same inputs = same output hash
- Hermetic - No access to network, filesystem outside /nix/store
- Reproducible - Build again, get same hash
- Cacheable - Hash lookup in binary caches
Viewing Derivations
Section titled “Viewing Derivations”# Show derivation for a packagenix derivation show nixpkgs#python3
# Show derivation pathnix-instantiate '<nixpkgs>' -A python3
# Show runtime dependenciesnix-store -q --tree /nix/store/...-python3-3.10.12
# Show build-time dependenciesnix-store -qR $(nix-instantiate '<nixpkgs>' -A python3)
The Nix Store
Section titled “The Nix Store”Structure
Section titled “Structure”The Nix store (/nix/store
) is an immutable directory where all packages live:
/nix/store/├── 1v3d2qj7k6vvkr7mprqnlk4p4yyk2r7d-python3-3.10.12/│ ├── bin/│ │ ├── python3│ │ └── pip3│ ├── lib/│ │ └── python3.10/│ └── share/├── abc123...-hello-2.10.drv # Derivation file├── abc123...-hello-2.10/ # Built package│ └── bin/│ └── hello└── xyz789...-gcc-11.3.0/ └── ...
Store Properties
Section titled “Store Properties”- Immutable - Files never modified after creation
- Content-addressed - Hash in path identifies contents
- Atomic - Builds either complete or don’t exist
- Garbage-collectible - Unused paths can be deleted safely
Store Operations
Section titled “Store Operations”# Query store pathnix-store -q /nix/store/...-python3
# Show dependenciesnix-store -q --references /nix/store/...-python3
# Show reverse dependencies (what depends on this)nix-store -q --referrers /nix/store/...-python3
# Verify store integritynix-store --verify --check-contents
# Optimize store (hardlink duplicates)nix-store --optimise
Store Database
Section titled “Store Database”Nix maintains a SQLite database of store paths:
# Location/nix/var/nix/db/db.sqlite
# Contains:# - All store paths# - Dependency relationships# - GC roots# - Binary cache info
Evaluation Model
Section titled “Evaluation Model”Lazy Evaluation
Section titled “Lazy Evaluation”Nix is lazily evaluated - expressions are only evaluated when their values are needed:
let expensive = import ./huge-calculation.nix; # Not evaluated yet result = expensive.someAttribute; # Only evaluates what's neededin result
Evaluation Phases
Section titled “Evaluation Phases”- Parse - Read
.nix
files into AST - Evaluate - Reduce expressions to values
- Instantiate - Convert values to derivations (.drv)
- Realise - Build derivations to store paths
# Just parse (check syntax)nix-instantiate --parse file.nix
# Evaluate to valuenix-instantiate --eval file.nix
# Instantiate to .drvnix-instantiate file.nix
# Realize (build)nix-build file.nix
Pure Functional Language
Section titled “Pure Functional Language”Nix expressions are pure functions:
# Pure - always returns same result{ pkgs }: pkgs.python3.withPackages (ps: [ ps.requests ps.flask ])
# Impure - depends on external state (not allowed in derivations)builtins.readFile /etc/hostname # Error in restricted mode
Evaluation Context
Section titled “Evaluation Context”During evaluation, Nix has:
- ✅ Access to all
.nix
files - ✅ Ability to import other modules
- ✅ Builtin functions (map, filter, etc.)
- ❌ No network access
- ❌ No arbitrary filesystem access
- ❌ No side effects
During build (in sandbox), Nix has:
- ✅ Access to declared inputs in
/nix/store
- ✅ Isolated temp directory
- ✅ Declared environment variables
- ❌ No network (except fixed-output derivations)
- ❌ No access to
/nix/store
outside inputs - ❌ No access to home directory,
/tmp
, etc.
Build Process
Section titled “Build Process”From Expression to Store Path
Section titled “From Expression to Store Path”-
Write Nix expression
{ pkgs }: pkgs.stdenv.mkDerivation {name = "hello";src = ./src;buildPhase = "gcc hello.c -o hello";installPhase = "mkdir -p $out/bin; cp hello $out/bin/";} -
Evaluation - Nix evaluates to derivation
/nix/store/abc123...-hello.drv nix-instantiate hello.nix -
Realisation - Nix builds derivation
/nix/store/xyz789...-hello nix-build hello.nix
Build Sandbox
Section titled “Build Sandbox”Every build runs in an isolated sandbox:
- Isolated filesystem - Only sees
/nix/store
inputs - Isolated network - No network access (except FODs)
- Isolated process tree - No access to other processes
- Clean environment - Only declared env vars
# Check sandbox statusnix show-config | grep sandbox
# Build with sandbox explicitly enablednix-build --option sandbox true hello.nix
Build Phases
Section titled “Build Phases”Standard build phases (from stdenv.mkDerivation
):
- unpackPhase - Extract source tarball
- patchPhase - Apply patches
- configurePhase - Run
./configure
- buildPhase - Run
make
- checkPhase - Run
make check
(optional) - installPhase - Copy outputs to
$out
- fixupPhase - Patch shebangs, strip binaries
Build Environment
Section titled “Build Environment”# During build, these are set:$out # Output path (e.g., /nix/store/xyz789...-hello)$src # Source path$buildInputs # List of dependencies$NIX_BUILD_CORES # CPU cores available$NIX_BUILD_TOP # Build directory
Binary Caches
Section titled “Binary Caches”What is a Binary Cache?
Section titled “What is a Binary Cache?”A binary cache stores pre-built derivations so you don’t have to build locally:
Your Computer Binary Cache (cache.nixos.org) │ │ │ 1. Request /nix/store/abc123...-hello ├─────────────────────────────────────>│ │ │ │ 2. Send .nar.xz (compressed package) │ │<─────────────────────────────────────┤ │ │ │ 3. Extract to /nix/store │ └──────────────────────────────────────
How It Works
Section titled “How It Works”- Hash lookup - Nix computes derivation hash
- Cache query - Checks if binary exists in cache
- Download - If found, download and extract
- Build - If not found, build locally
Configure Binary Caches
Section titled “Configure Binary Caches”# In nix.settingsnix.settings = { substituters = [ "https://cache.nixos.org" "https://nix-community.cachix.org" ]; trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" ];};
Binary Cache Operations
Section titled “Binary Cache Operations”# Query if path is in cachenix path-info --store https://cache.nixos.org /nix/store/...-hello
# Build without using cachesnix-build --option substitute false hello.nix
# Push to cachixcachix push my-cache /nix/store/...-hello
NAR Format
Section titled “NAR Format”Binary caches store packages as NAR (Nix ARchive) files:
.nar
- Uncompressed archive.nar.xz
- XZ-compressed (most common).nar.zst
- Zstandard-compressed (faster)
# Create NAR from store pathnix-store --export /nix/store/...-hello > hello.nar
# Import NARnix-store --import < hello.nar
Garbage Collection
Section titled “Garbage Collection”GC Roots
Section titled “GC Roots”GC roots prevent paths from being deleted:
GC Root → Derivation → Dependencies → ... → Leaf packages
Types of roots:
- User profiles -
~/.nix-profile
- System profiles -
/nix/var/nix/profiles/system
- Result symlinks -
./result
from nix-build - Explicit roots -
/nix/var/nix/gcroots/
Garbage Collection Process
Section titled “Garbage Collection Process”# Find unreachable pathsnix-store --gc --print-dead
# Delete unreachable pathsnix-store --gc
# Delete old generationsnix-collect-garbage --delete-older-than 30d
# Delete everything not currently in usenix-collect-garbage -d
How GC Works
Section titled “How GC Works”- Find roots - Start from GC roots
- Trace dependencies - Follow all references
- Mark live paths - Anything reachable is kept
- Sweep dead paths - Delete unreachable paths
Viewing GC Roots
Section titled “Viewing GC Roots”# List all GC rootsls -l /nix/var/nix/gcroots/
# Find roots for a store pathnix-store -q --roots /nix/store/...-python3
# Add a GC root manuallynix-store --add-root /nix/var/nix/gcroots/my-root /nix/store/...-hello
Fixed-Output Derivations
Section titled “Fixed-Output Derivations”What are FODs?
Section titled “What are FODs?”Fixed-Output Derivations are special derivations that:
- Have network access during build
- Declare expected output hash upfront
- Used for fetching sources (git, tarballs, etc.)
Why FODs are Special
Section titled “Why FODs are Special”Normal derivations:
- ❌ No network access
- ✅ Hash derived from inputs
Fixed-output derivations:
- ✅ Network access allowed
- ✅ Hash declared explicitly
- ✅ Nix verifies output matches hash
Example FOD
Section titled “Example FOD”{ pkgs }:pkgs.fetchurl { url = "https://example.com/hello-1.0.tar.gz"; sha256 = "abc123..."; # Expected hash}
Creating FODs
Section titled “Creating FODs”# fetchurlpkgs.fetchurl { url = "..."; sha256 = "...";}
# fetchgitpkgs.fetchgit { url = "..."; rev = "..."; sha256 = "...";}
# fetchFromGitHubpkgs.fetchFromGitHub { owner = "..."; repo = "..."; rev = "..."; sha256 = "...";}
Getting Hashes
Section titled “Getting Hashes”# Fetch and compute hashnix-prefetch-url https://example.com/file.tar.gz
# Fetch git and compute hashnix-prefetch-git https://github.com/user/repo
# Use fakeSha256, build will fail with correct hashsha256 = pkgs.lib.fakeSha256;
Quick Reference
Section titled “Quick Reference”Common Commands
Section titled “Common Commands”# Store operationsnix-store -q --tree /nix/store/...-pkg # Show dependency treenix-store -q --references /nix/store/...-pkg # List direct dependenciesnix-store --verify --check-contents # Verify store integrity
# Derivation operationsnix derivation show nixpkgs#hello # Show derivationnix-instantiate '<nixpkgs>' -A hello # Build .drv filenix-build '<nixpkgs>' -A hello # Build package
# Evaluationnix eval nixpkgs#hello.name # Evaluate attributenix-instantiate --eval '<nixpkgs>' -A hello.name
# Garbage collectionnix-collect-garbage # Delete unreachable pathsnix-collect-garbage -d # Delete old profiles toonix-store --gc --print-roots # Show all GC roots
# Binary cachesnix path-info --store https://cache.nixos.org /nix/store/...-pkgnix copy --to https://my-cache.com /nix/store/...-pkg
Key File Locations
Section titled “Key File Locations”/nix/store/ # All packages/nix/var/nix/profiles/ # User/system profiles/nix/var/nix/gcroots/ # GC roots/nix/var/nix/db/db.sqlite # Store database~/.nix-profile # User profile (symlink)/run/current-system # Current system (NixOS/Darwin)
Environment Variables
Section titled “Environment Variables”NIX_PATH="nixpkgs=/path/to/nixpkgs" # Search path for <nixpkgs>NIX_STORE_DIR="/nix/store" # Store location (usually default)NIX_BUILD_CORES=8 # Parallel build jobs
Related Documentation
Section titled “Related Documentation”- Structure Guide - Modular configuration explained
- Design Doc - Overall architecture and roadmap
- CLI Commands - Common Nix commands
- Modules Reference - All modules documented
- Troubleshooting - Common issues and solutions
External References
Section titled “External References”- Nix Manual - Official Nix documentation
- Nixpkgs Manual - Package repository guide
- Nix Pills - In-depth Nix tutorial series
- NixOS Wiki - Store - Store documentation
- Derivation Format - Derivation specification
Next: CLI Commands Reference - Learn common Nix commands