A recipe is not the meal.
A derivation records a builder, arguments, environment, inputs, and outputs. Evaluating an expression can produce this plan without performing the build itself. Realizing it obtains the output by building or substituting from a configured cache.
Most packages use helpers from Nixpkgs rather than constructing raw derivations. This tiny example uses runCommand to create a file as its output.
{ pkgs ? import <nixpkgs> {} }:
pkgs.runCommand "first-output" {} ''
mkdir -p "$out"
printf 'Made by Nix\n' > "$out/message.txt"
''
Meet the result link.
Save the file as default.nix and run these commands in that directory. nix-build creates a result symlink to the output. The builder’s $out is the assigned store destination.
This first recipe uses your current <nixpkgs> source. Later we will lock that source with a flake. A sandboxed build reduces accidental dependencies on your machine, but reproducible outputs also require well-behaved build tools.
nix-build
cat result/message.txt
readlink result
# message.txt contains: Made by Nix
Evaluation makes a plan; realization obtains the plan’s outputs.