Antiquotation and Paths¶
Overview¶
In Nix documentation, antiquotation usually means embedding expressions in a literal with ${…}—the same mechanism as string interpolation, but applied to path literals. A path antiquotation such as ./foo-${name}.nix keeps the result a path value while substituting name into the path text.
Path literals are a distinct type from strings. They resolve against the filesystem, can include lookup paths like <nixpkgs>, and behave differently when coerced to strings. General interpolation rules live in strings and interpolation; this page focuses on path syntax, resolution, and store copying.
Details¶
Path vs division. A path literal must contain at least one /. When ${…} appears, at least one slash must come before the first interpolation or the parser treats . as numeric division. ./a.${foo}/b is a path; a.${foo}/b is division.
Relative and absolute paths. Relative literals (./, ../, or segments without a leading /) resolve against the directory of the file being evaluated, not the working directory. Absolute paths (/etc/…) are valid but make expressions less portable; prefer relative paths for sources beside the .nix file, or a string literal when you only need a fixed filesystem location in config output. See literals.
Canonical form. Path values are normalized like realpath without following symlinks: no trailing slashes, no duplicate slashes, and no . or .. components remain in the value. The path does not need to exist on disk to be a valid path value.
Home paths. A leading ~ expands to the user's home directory (~/src → /home/user/src). These are forbidden in pure evaluation; see purity boundaries and pure eval and impure.
Lookup paths. Tokens such as <nixpkgs> or <nixpkgs/lib> are lookup path literals. They resolve to path values via NIX_PATH (or flake equivalents in locked workflows). Prefer pinning inputs in flakes over implicit lookup paths when reproducibility matters.
Path antiquotation. Inside a path literal, ${expr} may appear after the required slash. The expression must evaluate to a string or path (or an attribute set with __toString / outPath as for string interpolation). Each segment is concatenated into the path text before resolution rules apply.
Coercion and the store. Converting a path to a string—via "${./src}", concatenating a string with a path ("prefix-" + ./file), or similar—requires the path to refer to a readable file or directory. Nix copies that content into the store and uses the resulting store path string. This is how ./source.nix and ${./src} end up as fixed, content-addressed inputs in derivations. Path values used without string coercion (e.g. passed to import) do not automatically copy to the store.
Examples¶
Path antiquotation vs division.
let name = "default";
in {
config = ./foo-${name}.nix; # path
# broken = foo-${name}.nix; # parsed as division, not a path
}
Relative resolution. In /projects/pkg/default.nix, ./src means /projects/pkg/src.
Lookup path.
Store copy on coercion.
Home path (impure eval only).
References¶
- Nix language syntax — Path — path literals, slashes, interpolation, lookup paths
- String interpolation —
${…}in paths and strings - Nix language types — Path — canonical paths and store copying