I am writing an application that needs, at runtime, to download resources from the internet and pre-process them. But I want to skip the work on subsequent launches.

This seems exactly the problem solved by build.zig. Is there a nice way to re-use that in my application? The brute-force would be to ship zig together with my application, and then, at runtime, materialize build.zig on disk and shell out to bundled zig.

Is there some way to do essentially that, but statically compiling everything into my app? Should I maybe just use the Cache directly? Any examples I can learn from?

alanza July 13, 2026, 6:49pm 2

@kristoff’s Zine SSG used to do exactly this. I’m not sure whether it still does, but as a user of Zine you no longer write a build.zig.

Yes in the beginning Zine depended on the Zig build system to orchestrate the build.

But at some point I decided to bite the bullet and write my own “vertically integrated” build pipeline. My reasoning at the time was that I wanted to do incremental rebuilds of the website, and Zine has dependencies that get discovered at make time, which are annoying to index in a way that makes sense for the Zig build system.

In the end turns it out that after doing everything in myself in a single process, builds are now so fast that I haven’t reimplemented yet any support for incremental builds.

But I don’t bundle any of Zig, it’s all homegrown.

Having a lightweight build system as a library sounds cool, but it’s one of those problems where people have vastly different needs and it’s hard to make a general solution that can be good enough for anybody.

That said… the Zig build maker is now a fully separate process from the configurer, which means that it would definitely be possible to create a light-weight alternative configurer “frontend”, maybe one that takes in a config file instead of a Zig source file, and have that generate the graph for the maker.

That could be limited to essentially having the maker cache addSystemCommand steps, unless you do decide to bundle all of Zig.

This was the same question I had to answer when I started anyzig. My solution was to add zig itself as a dependency and include it’s fetch code (maybe it’s caching code too, I can’t remember now). I actually wrote the initial version of anyzig while waiting in an airport and was pleasantly surprised to see it work just before I had to board the plane :slight_smile:

I used a trick to unlock access to everything I needed inside zig’s sometimes non-public APIs by adding a single file to the zig module which could import and re-expose anything I needed, which turned out to just be this:

This is easy to setup with a few lines of build.zig

    const write = b.addWriteFiles();
    _ = write.addCopyDirectory(zig_dep.path("."), "", .{});
    const root = write.addCopyFile(b.path("zigroot/root.zig"), "src/root.zig");
    const zig_mod = b.createModule(.{
        .root_source_file = root,
    });

I’m not sure if this is the route I’d go for your use case but thought it might be interesting to see how easy it is to do things like this with Zig.