Zig 0.16 rewrites the contract between code and I/O, speeds up incremental builds by changing the compiler dependency model — and once again demonstrates that version 1.0 for the team is not the goal of the quarter, but a matter of principle.
- std.Io: async without “function color” class=»notranslate»>__GTAG8__ The main change in the release is std.Io as an interface, and not a primitive built into the language, emphasizes xrust. Previously, in most languages with async/await, functions were divided into “colored” ones: a regular function cannot directly call an asynchronous one, and vice versa, without binding. Zig solves this differently: I/O is passed as a regular parameter, along with an allocator. zig pub fn main(init: std.process.Init) !void { const gpa = init.gpa; const io = init.io; std.log.info(«{d} env vars», .{init.environ_map.count()}); } This is “Juicy Main” — dependency injection for the program entry point: one parameter process.Init gives access to the general-purpose allocator, Io implementation, environment variable map and CLI arguments without manually initializing each piece of runtime separately. Practical consequence: the same code with std.Io can be executed on both a streaming backend and an event backend — io_uring on Linux, Grand Central Dispatch on macOS — without rewriting function signatures. The choice of implementation remains on the side of the calling code, rather than being dictated by the language via async/await as a separate syntactic entity. Type resolution: from cycle in DAG In March, Matthew Lugg contributed a 30,000-line edit that reworked the compiler's internal dependency graph from a cyclic structure to a directed acyclic graph (DAG). Previously, the graph allowed cycles, which complicated the analysis and slowed down incremental rebuilds. DAG does two things: it makes it easier for the compiler to determine what really needs to be recalculated when editing a file, and when a cyclic dependency is detected in user code, the error message becomes readable, rather than an abstract trace through a dozen intermediate nodes. Working with package dependencies has been simplified separately — they have moved to the local project directory instead of the global cache, which reduces the number of surprises when deploying someone else's project on a new machine. What has changed in platform support Native CI testing expanded to aarch64, loongarch64, powerpc64le, s390x; added cross-compilation for aarch64-maccatalyst and x86_64-maccatalyst; initial support for loongarch32-linux has appeared; long-standing bugs of the standard library on weakly-ordered architectures and platforms with non-standard page sizes have been fixed — reliability on AArch64 (especially without LSE), LoongArch and Power ISA has noticeably increased; big-endian ARM now correctly issues BE8 format object files instead of the outdated BE32 when targeting ARMv6+; Crash stack trace now works on almost all major targets. The requirement for post-1.0 releases is stated directly in the release notes: Tier 1 platforms must have zero disabled tests. This has not yet been fulfilled — and, accordingly, the condition for 1.0 has not been met. Why not 1.0 The team's position is discussed in detail in the June JetBrains article «Why Zig Isn't 1.0 (Yet)»: the question asked before every potentially irreversible decision is what the team would regret if they fixed it in the standard right now. Andrew Kelly admits that the 1.0 label would speed up corporate adoption of the language, but does not deliberately force the release. Zig exists on donations through a non-profit foundation, rather than venture capital money — this gives freedom not available to VC-backed competitors who need to present growth metrics to investors here and now. Analytics For practicing developers, the key release signal is not specific features, but the approach to async itself. An explicit Io parameter removes the classic functional color problem, familiar to anyone who has written in languages with mandatory async/await: the inability to beautifully mix synchronous and asynchronous code in the same codebase. Zig's solution is conceptually similar to what the language has already done with memory management — making the allocator an explicit parameter instead of hidden runtime. For system programming, embedded and high-load services, this is a meaningful compromise: a little more explicit code in signatures in exchange for predictability and the absence of hidden allocations. The constant rejection of version 1.0 does not interfere with production use — the community on Habré in a separate Zig hub regularly discusses combat cases, and the compiler’s own backend (rejection of LLVM for some targets) reduces external dependencies of the language. Rust went to 1.0 for about nine years — against this background, the current ten-year path of Zig without a release does not look like an anomaly; rather, it continues the tradition of system languages of not rushing to fix the standard. Other news While Zig is demonstratively slowing down, Mojo is going in the opposite direction: the first beta version of Mojo 1.0 was released in early May, which the project team assesses as almost ready for mass use, and the final stable release is promised this fall. Sources: https://ziglang.org/download/0.16.0/release-notes.html https://blog.bokvi.com/blog/zig-in-2026/ https://sesamedisk.com/zig-2026-momentum-ongoing-development/ Xrust Zig 0.16: the color of functions is canceled, but before 1.0 — fundamentally not
- Type resolution: from cycle in DAG
- What has changed in platform support
- Why not 1.0
- Analytics
- Other news
std.Io: async without “function color” class=»notranslate»>__GTAG8__
The main change in the release is std.Io as an interface, and not a primitive built into the language, emphasizes xrust. Previously, in most languages with async/await, functions were divided into “colored” ones: a regular function cannot directly call an asynchronous one, and vice versa, without binding. Zig solves this differently: I/O is passed as a regular parameter, along with an allocator.
zig
pub fn main(init: std.process.Init) !void {
const gpa = init.gpa;
const io = init.io;
std.log.info(«{d} env vars», .{init.environ_map.count()});
}
This is “Juicy Main” — dependency injection for the program entry point: one parameter process.Init gives access to the general-purpose allocator, Io implementation, environment variable map and CLI arguments without manually initializing each piece of runtime separately.
Practical consequence: the same code with std.Io can be executed on both a streaming backend and an event backend — io_uring on Linux, Grand Central Dispatch on macOS — without rewriting function signatures. The choice of implementation remains on the side of the calling code, rather than being dictated by the language via async/await as a separate syntactic entity.
Type resolution: from cycle in DAG
In March, Matthew Lugg contributed a 30,000-line edit that reworked the compiler's internal dependency graph from a cyclic structure to a directed acyclic graph (DAG). Previously, the graph allowed cycles, which complicated the analysis and slowed down incremental rebuilds. DAG does two things: it makes it easier for the compiler to determine what really needs to be recalculated when editing a file, and when a cyclic dependency is detected in user code, the error message becomes readable, rather than an abstract trace through a dozen intermediate nodes.
Working with package dependencies has been simplified separately — they have moved to the local project directory instead of the global cache, which reduces the number of surprises when deploying someone else's project on a new machine.
What has changed in platform support
- Native CI testing expanded to aarch64, loongarch64, powerpc64le, s390x;
- added cross-compilation for aarch64-maccatalyst and x86_64-maccatalyst;
- initial support for loongarch32-linux has appeared;
- long-standing bugs of the standard library on weakly-ordered architectures and platforms with non-standard page sizes have been fixed — reliability on AArch64 (especially without LSE), LoongArch and Power ISA has noticeably increased;
- big-endian ARM now correctly issues BE8 format object files instead of the outdated BE32 when targeting ARMv6+;
- Crash stack trace now works on almost all major targets.
The requirement for post-1.0 releases is stated directly in the release notes: Tier 1 platforms must have zero disabled tests. This has not yet been fulfilled — and, accordingly, the condition for 1.0 has not been met.
Why not 1.0
The team's position is discussed in detail in the June JetBrains article «Why Zig Isn't 1.0 (Yet)»: the question asked before every potentially irreversible decision is what the team would regret if they fixed it in the standard right now. Andrew Kelly admits that the 1.0 label would speed up corporate adoption of the language, but does not deliberately force the release. Zig exists on donations through a non-profit foundation, rather than venture capital money — this gives freedom not available to VC-backed competitors who need to present growth metrics to investors here and now.
Analytics
For practicing developers, the key release signal is not specific features, but the approach to async itself. An explicit Io parameter removes the classic functional color problem, familiar to anyone who has written in languages with mandatory async/await: the inability to beautifully mix synchronous and asynchronous code in the same codebase. Zig's solution is conceptually similar to what the language has already done with memory management — making the allocator an explicit parameter instead of hidden runtime. For system programming, embedded and high-load services, this is a meaningful compromise: a little more explicit code in signatures in exchange for predictability and the absence of hidden allocations.
The constant rejection of version 1.0 does not interfere with production use — the community on Habré in a separate Zig hub regularly discusses combat cases, and the compiler’s own backend (rejection of LLVM for some targets) reduces external dependencies of the language. Rust went to 1.0 for about nine years — against this background, the current ten-year path of Zig without a release does not look like an anomaly; rather, it continues the tradition of system languages of not rushing to fix the standard.
Other news
While Zig is demonstratively slowing down, Mojo is going in the opposite direction: the first beta version of Mojo 1.0 was released in early May, which the project team assesses as almost ready for mass use, and the final stable release is promised this fall.
Sources:
- https://ziglang.org/download/0.16.0/release-notes.html
- https://blog.bokvi.com/blog/zig-in-2026/
- https://sesamedisk.com/zig-2026-momentum-ongoing-development/
Xrust Zig 0.16: the color of functions is canceled, but before 1.0 — fundamentally not
- Если Вам понравилась статья, рекомендуем почитать
- Hackers infected hundreds of npm packages with ransomware
- WordPress is under attack: critical WP2Shell vulnerability is already being exploited






