← docs1 min read

7. Configuration

A config block declares knobs. The base block is unnamed; named overlays are applied on top with @name at invocation. Values are declared on the var sink…

manual

A config block declares knobs. The base block is unnamed; named overlays are applied on top with @name at invocation. Values are declared on the var sink (var.NAME = ...), read only through $<...> placeholders, and every consulted one folds into the cache key. A config body is a sandbox: its one external channel is the host surface — host.os, host.arch, host.env("NAME", "default"), and host.read("path") — so the block stays a pure function of the facts it reads.

config
var.MODE = host.env("MODE", "debug")
config release
var.MODE = "release"
recipe build
gather "src/*.c"
cook "build/$<in.stem>.o" { gcc -c -DMODE=$<MODE> $<in> -o $<out> }
Terminal window
cook build # MODE=debug (the base)
cook build @release # apply the `release` overlay → MODE=release
cook --set MODE=tiny build # a one-shot override that wins over everything

Flipping a declared value cleanly busts only the units that consumed it. A $<KEY> for a variable you never declared is a hard error, and a var.* value never enters a step’s process environment — the only way to read it is $<KEY>, which keeps it in the cache key. No accidental shell leaks.