NOW LET US – AI RAG SaaS Studio TP.HCM
NOW LET US
Digital Product Studio
Back to news
DEV-TOOLS...6 min read

Zig: All Package Management Functionality Moved from Compiler to Build System

Share
NOW LET US Article – Zig: All Package Management Functionality Moved from Compiler to Build System

The latest Zig devlog highlights the migration of package management from the compiler to the build system, alongside major updates and performance improvements for the SPIR-V backend.

Devlog

This page contains a curated list of recent changes to main branch Zig.

Also available as an RSS feed.

This page contains entries for the year 2026. Other years are available in the Devlog archive page.

Author: Andrew Kelley

Now that there is a separate process for usersâ build.zig scripts and the build system itself, it makes sense for that to be the place that package management logic lives.

I moved these subcommands to the maker process:

zig build

zig fetch

zig init

zig libc

This means that large parts of what used to be included in the compiler executable are now shipped in source form instead, including:

  • package fetching logic
  • HTTP client and networking
  • TLS (Transport Layer Security) and associated crypto
  • Git protocol
  • xz, gzip, zstd, flate, zip
  • parsing, validation, and otherwise dealing with build.zig.zon

files

Consequently, this functionality can now be patched without rebuilding the compiler, making it easier for users and contributors to tinker.

Furthermore, it means that package management in zig now has safety checks enabled when doing networking, since the maker executable is compiled in ReleaseSafe

mode. Plus, all the crypto used for networking and file hashing can now take advantage of special CPU instructions available on the host, even the ones that are too rare to normally depend on when distributing software. We can have AOT cake and eat JIT, too!

My original motivation for doing this was in relation to exposing a build server protocol in order to unblock ZLS after maker/configurer process separation made breaking changes to the --build-runner

override flag.

Originally, the process tree looked like this:

zig build (the zig compiler + package manager)
ââ builder (the user's build.zig logic + build system implementation)

The process separation changeset made it look like this instead:

zig build (the zig compiler + package manager)
ââ configurer (the user's build.zig logic)
ââ maker (build system)

At this point, consider a long-running zig build --watch

process, watching files and rebuilding on source code changes. If any changes to build.zig

are detected, or any files observed during execution of that logic, it means configurer

needs to be rerun, meaning that maker

process must exit to give zig build

a chance to repeat the package management logic.

Now, after the changes described in this devlog entry, it looks like this:

zig build (the zig compiler)
ââ maker (build system + package manager)
ââ configurer (the user's build.zig logic)

Thus, when configuration needs to be rerun, maker

process can continue to live because it is the parent process rather than a sibling. In terms of the upcoming build server, it means avoiding an awkward situation where the server has to exit and the client has to reconnect, rather than simply informing the client of a configuration change.

This is almost entirely a non-breaking change, but there are some observable differences:

  • Zig executable binary size: shrinks 4% from 14.1 to 13.5 MiB (no LLVM, ReleaseSmall) --maker-opt

flag is replaced byZIG_DEBUG_MAKER

environment variable--zig-lib-dir

flag is replaced byZIG_LIB_DIR

environment variable

The follow-up issues to this changeset are the main blockers until we tag Zig 0.17.0:

  • build server protocol MVP (needed to unblock ZLS)
  • introduce the concept of adding path dependencies of the build script itself
  • make zig build --watch

detect modifications to the build script and rerun itself - different cwd causes build script cache miss

I have two conferences coming up in July and I need to work on my talks, so being realistic, I donât think I will have time to wrap these up until early August. Contributions welcome, of course.

Big thanks to Techatrix from the ZLS team for reaching out and working with me on the build server protocol! They are seeking sponsorship, by the way.

Author: Ali Cheraghi

Thereâs quite a bit to cover. The SPIR-V backend had bitrotted in a number of places after the recent compiler changes, so I spent the past several weeks dragging it into a better state.

@SpirvType

SPIR-V has a handful of types that couldnât be expressed in Zigâs type system. The new @SpirvType

builtin has been introduced to address the longest-standing blocker for writing shaders. See #20550, #23326 and #35461 to trace the background.

const Sampler = @SpirvType(.sampler);
const Image = @SpirvType(.{ .image = .{
.usage = .{ .sampled = u32 },
.format = .unknown,
.dim = .@"2d",
.depth = .unknown,
.arrayed = false,
.multisampled = false,
.access = .unknown,
} });
const SampledImage = @SpirvType(.{ .sampled_image = Image });
const RuntimeArray = @SpirvType(.{ .runtime_array = u32 });
const sampled_image = @extern(*addrspace(.constant) const SampledImage, .{
.name = "sampled_image",
.decoration = .{ .descriptor = .{ .set = 0, .binding = 1 } },
});

Execution Mode on the Calling Convention

Execution mode info (workgroup size, fragment origin, etc.) is now carried by the calling convention instead of being emitted via inline assembly OpExecutionMode

. The old std.gpu.executionMode()

helper is gone, and the SPIR-V assembler now rejects manual OpExecutionMode

instructions. Two new calling conventions, spirv_task

and spirv_mesh

, were also added for mesh shading pipelines.

export fn vert() callconv(.spirv_vertex) void {}
export fn frag() callconv(.{ .spirv_fragment = .{ .depth_assumption = .greater } }) void {}
export fn comp() callconv(.{ .spirv_kernel = .{ .x = 8, .y = 8, .z = 1 } }) void {}
export fn task() callconv(.{ .spirv_task = .{ .x = 1, .y = 1, .z = 1 } }) void {}
export fn mesh() callconv(.{ .spirv_mesh = .{ .stage_output = .output_lines, .max_primitives = 1, .max_vertices = 2 } }) void {}

Capabilities and Extensions from CPU Features

Capabilities and extensions used to be emitted ad hoc by codegen or via inline assembly. Theyâre now driven entirely by the CPU feature set like other targets, with dependency chains extracted from SPIRV-Headers (excluding external vendors for now), and the assembler now rejects any attempt to emit OpCapability

or OpExtension

directly.

Multi-Threaded Codegen

From day one, the SPIR-V backend ran codegen single-threaded inside the linker thread. Each codegen job now produces an Mir

value just like every other self-hosted backend, and gets scheduled on the compilerâs thread pool.

The same change brought back two ISel passes that had been removed during earlier refactors: dedup_types

(which merges equivalent type instructions) and prune_unused

(which strips dead code from the final module). These had originally been deleted back when codegen was single-threaded.

Object File Linking

.spv

files are now recognised as object files. You can compile multiple .zig

files (or external .spv

objects) and have the SPIR-V linker stitch them into a single module.

Tens of bugs have also been fixed along the way with a nearly 10% increase in total passing behavior tests (49% now) on the spirv64-vulkan

target, std.gpu

was renamed to std.spirv

and the SPIR-V backend is meaningfully more useful than it was a month ago, but thereâs still a long way to go. Plenty of behavior tests remain skipped on SPIR-V. That said, if youâve been on the fence about trying Zig for shaders or compute kernels, this is a good time to give it a shot. Bug reports are very welcome on Codeberg. Happy hacking!

Author: Matthew Lugg

(Quite long devlog coming up, apologiesâI got a little carried away with this one!)

A few weeks ago, I began working on a branch implementing an improvement to the LLVM backend which had been planned for a long time. This ended up snowballing into a bigger change which implemented a few language proposals you might be interested to hear about.

LLVM Backend Integer Lowering

Zig has always lowered arbitrary bit-width integer

© 2026 Now Let Us. All rights reserved.

Source: Hacker News

Advertisement
Ad slot ready: 5887729102

More in this category

NOW LET US Related – Fast Software, the Best Software

dev-tools

Fast Software, the Best Software

Speed is more than just a feature; it is a direct reflection of engineering quality and reliability. This article explores why fast, responsive software wins user trust and how feature bloat ruins once-great applications.

NOW LET US Related – Is The Economist Always Wrong?

dev-tools

Is The Economist Always Wrong?

Often dubbed the 'voice of God' yet sometimes ridiculed as a 'contrarian indicator,' The Economist used the AI model GPT-5.5 to analyze over 7,000 of its editorials since 2000, revealing a fascinating track record of hits and misses.

NOW LET US Related – sqlite-utils 4.0rc2, mostly written by Claude Fable (for about $149.25)

dev-tools

sqlite-utils 4.0rc2, mostly written by Claude Fable (for about $149.25)

The author of sqlite-utils shares how they leveraged the Claude Fable AI agent to identify and fix critical transaction bugs for the 4.0rc2 release, costing an estimated $149.25 in API usage.

NOW LET US Related – Megawatts by Microwave

dev-tools

Megawatts by Microwave

The historical journey of how the US Army and the Bonneville Power Administration (BPA) overcame geographical barriers to build the first integrated regional power grid, laying the foundation for modern energy infrastructure.

NOW LET US Related – Shadcn/UI now defaults to Base UI instead of Radix

dev-tools

Shadcn/UI now defaults to Base UI instead of Radix

shadcn/ui has officially made Base UI its default component library, replacing Radix. The transition comes after strong community adoption, though Radix remains fully supported with no forced migrations.

NOW LET US Related – Moby Dick Workout (2022)

dev-tools

Moby Dick Workout (2022)

How much content can your productivity app handle before lagging? The "Moby Dick Workout" is a simple yet effective benchmark to test the performance limits of your daily note-taking and outliner tools.

EXPLORE TOPICS

Discover All Categories

Deep dive into the specific technology sectors that matter most to you.