references and closures
how nix tracks what depends on what, and what that means for your builds.
nix needs to know which paths a built package actually uses at runtime. not which ones the derivation declared as build inputs: which ones ended up embedded in the output itself.
the reference scanner
after a build completes, nix scans every file in the output. it searches for 32-character strings from nix's base-32 alphabet. any sequence that matches a known store path hash is a reference. that path's hash was found in the output, so the output needs that path at runtime.
the scanner is not parsing ELF headers or interpreting shebangs. it is a string search. it finds the hash, records the dependency.
every path a built package references gets stored in nix's database for that output path.
closures
references compose. if curl references openssl, and openssl references glibc, then anything that needs curl also needs openssl and glibc.
the complete transitive set of a path and everything it references, recursively, is its closure.
curl-8.18.0 has 14 direct references and a closure of 22 paths. about 60 MiB total. that is what ships when you deploy curl with nix.