Zig 0.17 evaluates build.zig in a separate process from the one that runs the build
Zig 0.17.0 splits zig build into two executables, a configurer that evaluates build.zig and a maker that runs the build graph, according to a dev.to post. Script edits no longer rebuild the maker, while skipping the configure step as well requires build scripts that declare their host dependencies.
The Engineer · Build desk

What happened
- Probing the host at configure time, such as checking whether scdoc is installed, now has a name: configure cache poisoning.
- Four new declaration functions and a lazy findProgramLazy lookup let scripts declare file inputs or push tool searches to make time.
- Passing --listen=- starts a Build Server Protocol on stdin/stdout that lets IDEs inspect the graph and request specific steps.
Why it matters
- What it limits constraint A build.zig that probes the host at configure time keeps the configurer running on every invocation, so only scripts written to be pure get the skip.
- Who has to decide decision Maintainers porting large build scripts have to choose, probe by probe, between configure-time findProgram and findProgramLazy or a declared dependency.
- What's now possible capability Editors and other tools can read a project's build graph statically from the serialized configuration, without parsing or running build.zig themselves.
Next story · Build · Oct 2
Lightpanda 1.0 makes a browser without a renderer a production option for crawlers and agentsConfirmed2 publishers
Before 0.17, build.zig ran inside the build system's own process, so editing the script meant rebuilding the build system [6]. Every invocation after an edit started from scratch: recompile the build runner, re-evaluate the script, then execute the graph [7]. According to the dev.to post that walks through the release, that cost is a rounding error for small projects and compounds for large projects with complex build scripts [8]. The post does not include timings.
An edit in 0.17 still costs something. build.zig is Zig source that runs at configure time [9]. The configurer is the process that evaluates it [1], so a changed script still goes through the configurer [18]. What an edit no longer touches is the maker, which is built once and left unmodified when build.zig changes [10]. The maker is also built with optimizations enabled. The post says that matters more now that --watch and --fuzz modes exist [11].
For the large-project claim to transfer to a given tree, two things have to be true. The maker rebuild has to have been a real share of what an edit cost before. And the script has to keep the configure cache clean between runs.
The second condition is the harder one. The configurer can be skipped on identical inputs, but only while the cache stays pure [13]. Some CLI flags bypass configuration entirely [12]. A poisoned cache means the configure logic had side effects or did something the cache could not track [14]. The post's example is a build.zig that checks whether scdoc is installed to decide whether to build man pages. The result depends on host state the cache cannot see, so the cache is poisoned [14]. That is a lot of cache to lose over a man page. Side effects at make time are expected: a Run step that prints output does not poison anything [15].
Porting a large script means finding each configure-time probe and moving it to one of two forms. Four declaration functions cover file contents, file metadata (size, inode, mtime), directory contents and directory metadata, through calls such as std.Build.dependOnFileContents and std.Build.dependOnDirectoryContents [16]. For tool lookups, findProgram still exists for cases that need the answer at configure time. The new findProgramLazy returns a LazyPath that defers the search to make time [17].
I think the serialization boundary is the best engineering in the release. The configurer writes a compact binary serialization of the build graph, and the maker reads it [2]. Third-party tools can consume the same format, and it is the foundation of the new Build Server Protocol [5]. One artifact gives the cache something to key on and gives tools something to read. Passing --listen=- starts the server on stdin/stdout. IDEs can then inspect the graph statically, get notified when steps start and complete, and request specific steps [3]. The post calls the protocol early. Today it exposes available steps, options and dependencies, and module names plus a multiplexed compiler server protocol for type information and refactoring are planned [4].
What to watch
- Post-edit build timings from a large Zig codebase on the previous release and 0.17 would show whether the maker rebuild was a large share of the old cost.
- Whether the Build Server Protocol ships the module names and multiplexed compiler server protocol the post lists as planned.
- How many widely used build.zig files still call findProgram at configure time after porting, keeping the configurer on every run.
Clarity's read
What the record supports and how the coverage leans. The claims behind it follow.
Reality
- Evidence55
- Adoption30
- Hype gap+15
- Incentives
- Not scored
- Confidence55
Claim ledger
Ranked by verification strength, evidence, and original report placement.
- [1]
Zig 0.17.0 splits the build system into two separate executables: a configurer that evaluates build.zig and a maker that executes the build graph.
- [2]
The configurer process evaluates build.zig and produces a compact binary serialization of the build graph; the maker process consumes that serialization and executes the steps.
- [3]
Passing --listen=- starts the Build Server Protocol on stdin/stdout, letting IDEs and other tools inspect the build graph statically, receive notifications when steps start and complete, and request specific steps to build.
- [4]
The Build Server Protocol is still early; it exposes available steps, options and dependencies, and planned additions include module names and a multiplexed compiler server protocol for type information and refactoring.
- [5]
The serialized configuration is in a format third-party tooling can consume, and that format is the foundation of the new Build Server Protocol.
- [6]
Under the previous design, build.zig ran inside the build system's own process, so changing build.zig meant the build system itself had to be rebuilt.
- [7]
Before 0.17, every invocation after a build.zig edit started from scratch: recompile the build runner, re-evaluate the script, then execute the graph.
- [8]
The post says the rebuild cost is a rounding error for small projects and compounds for large projects with complex build scripts.
- [9]
build.zig is Zig source code that runs at configure time to declare what steps exist, what dependencies connect them, and what options are available.
- [10]
The maker executable is built once and remains unmodified when build.zig changes.
- [11]
The maker is built with optimizations enabled, which the post says matters more now that --watch and --fuzz modes exist.
- [12]
The configurer can be skipped entirely for certain CLI flags, so some zig build invocations go straight to the maker.
- [13]
When dependencies are declared instead of probed, the cache stays pure and the configurer can be skipped on identical inputs.
- [14]
A poisoned configure cache means the configure logic had side effects or did something the cache could not track; checking at configure time whether scdoc is installed to choose whether to build man pages poisons the cache because the result depends on host state the cache cannot see.
- [15]
A Run step that prints output has side effects at make time, which is expected and does not poison the cache.
- [16]
Four declaration functions cover file contents, file metadata (size, inode, mtime), directory contents and directory metadata, with examples std.Build.dependOnFileContents and std.Build.dependOnDirectoryContents.
- [17]
findProgram still exists for cases that need the result at configure time; a new findProgramLazy function returns a LazyPath that defers the search to make time.
- [18]
After a build.zig edit in 0.17, the configurer still has to evaluate the changed script; the maker is the part spared from rebuilding.
Sources
2 independent publishers whose own reporting we read for this story.
- dev.toZig 0.17 Split Its Build Into Two Processes: Why That Matters
1 article · October 3, 2026
- lwn.netZig 0.17 released
1 article · October 3, 2026
Topics and entities
Topics
- Language Servers
- Build Systems and Cross-Compilation
- Incremental compilation
Entities
- Zig Build Server Protocol
- Zig