<rss version="2.0">
 <channel>
  <title>Zig Devlog</title>
  <link>https://ziglang.org/devlog/</link>
  <description>Devlog</description>
  <generator>Zine -- https://zine-ssg.io</generator>
  <language>en-us</language>
  <lastBuildDate>Fri, 15 May 2026 00:04:29 +0000</lastBuildDate>
  
   <item>
    <title>Incremental compilation with LLVM
</title>
    <description>&lt;div id=&quot;2026-04-08&quot;&gt;&lt;h1&gt;&lt;a class=&quot;&quot; href=&quot;#2026-04-08&quot;&gt;Incremental compilation with LLVM&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;Author: Matthew Lugg&lt;/p&gt;&lt;p&gt;I’ve been spending a bit of time working on personal projects after merging my &lt;a href=&quot;#2026-03-10&quot;&gt;type resolution changes&lt;/a&gt; last month, but I did find the time recently to make some improvements to the LLVM codegen backend. This involved a few different enhancements with various goals, but one nice user-facing change was that I managed to get incremental compilation working with the LLVM backend.&lt;/p&gt;&lt;p&gt;Sadly this can’t do anything to speed up the dreaded LLVM Emit Object: that time is entirely down to LLVM. However, what incremental compilation &lt;em&gt;does&lt;/em&gt; help with is minimizing the time spent in the actual Zig compiler code, which means that if your code has compile errors (so “LLVM Emit Object” will be skipped), you’ll usually get those errors very quickly. (Of course, it does still give you a &lt;em&gt;slight&lt;/em&gt; speed-up in successful builds too.)&lt;/p&gt;&lt;p&gt;This support is available in master branch builds right now, and will be in the 0.16.0 release (which we’ll be tagging very soon).&lt;/p&gt;&lt;p&gt;For anyone who still hasn’t tried it, especially if you’re using Zig’s master branch, please do try out incremental compilation by passing &lt;code&gt;-fincremental --watch&lt;/code&gt; to &lt;code&gt;zig build&lt;/code&gt;! The Zig core team have benefited from incremental compilation in our workflows for a good year now, and we’re also hearing good things from users. The feature is relatively stable at this point, and people are often surprised how much time they can save just by getting up-to-date compile errors in milliseconds rather than seconds.&lt;/p&gt;&lt;p&gt;I haven’t really personally used incremental compilation with the LLVM backend, but all of the incremental test coverage in CI is now enabled for the LLVM backend, and I’ve had positive feedback from users, so it’s definitely worth giving a shot. As always, if you encounter bugs in incremental compilation, please report them if you can!&lt;/p&gt;&lt;p&gt;Thank you, and I hope you find this useful :)&lt;/p&gt;&lt;/div&gt;</description>
    <link>https://ziglang.org/devlog/2026/#2026-04-08</link>
    <pubDate>Wed, 08 Apr 2026 00:00:00 +0000</pubDate>
    <guid>https://ziglang.org/devlog/2026/#2026-04-08</guid>
   </item>
  
   <item>
    <title>Type resolution redesign, with language changes to taste
</title>
    <description>&lt;div id=&quot;2026-03-10&quot;&gt;&lt;h1&gt;&lt;a class=&quot;&quot; href=&quot;#2026-03-10&quot;&gt;Type resolution redesign, with language changes to taste&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;Author: Matthew Lugg&lt;/p&gt;&lt;p&gt;Today, &lt;a href=&quot;https://codeberg.org/ziglang/zig/pulls/31403&quot; target=&quot;_blank&quot;&gt;I merged a 30,000 line PR&lt;/a&gt; after two (arguably three) months of work. The goal of this branch was to rework the Zig compiler’s internal type resolution logic to a more logical and straightforward design. It’s a quite exciting change for me personally, because it allowed me to clean up a bunch of the compiler guts, but it also has some nice user-facing changes which you might be interested in!&lt;/p&gt;&lt;p&gt;For one thing, the Zig compiler is now lazier about analyzing the fields of types: if the type is never initialized, then there’s no need for Zig to care what that type “looks like”. This is important when you have a type which doubles as a namespace, a common pattern in modern Zig. For instance, when using &lt;code&gt;std.Io.Writer&lt;/code&gt;, you don’t want the compiler to also pull in a bunch of code in &lt;code&gt;std.Io&lt;/code&gt;! Here’s a straightforward example:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;bad_field&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@compileError&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;i am an evil field, muahaha&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;something&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;something&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// `Foo` only used as a namespace&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Previously, this code emitted a compile error. Now, it compiles just fine, because Zig never actually looks at the &lt;code&gt;@compileError&lt;/code&gt; call.&lt;/p&gt;&lt;p&gt;Another improvement we’ve made is in the “dependency loop” experience. Anyone who has encountered a dependency loop compile error in Zig before knows that the error messages for them are entirely unhelpful—but that’s now changed! If you encounter one (which is also a bit less likely now than it used to be), you’ll get a detailed error message telling you exactly where the dependency loop comes from. Check it out:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;inner&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Bar&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Bar&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;align&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@alignOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$ zig build-obj repro.zig
error: dependency loop with length 2
    repro.zig:1:29: note: type &amp;apos;repro.Foo&amp;apos; depends on type &amp;apos;repro.Bar&amp;apos; for field declared here
    const Foo = struct { inner: Bar };
                                ^~~
    repro.zig:2:44: note: type &amp;apos;repro.Bar&amp;apos; depends on type &amp;apos;repro.Foo&amp;apos; for alignment query here
    const Bar = struct { x: u32 align(@alignOf(Foo)) };
                                               ^~~
    note: eliminate any one of these dependencies to break the loop
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Of course, dependency loops can get much more complicated than this, but in every case I’ve tested, the error message has had enough information to easily see what’s going on.&lt;/p&gt;&lt;p&gt;Additionally, this PR made big improvements to the Zig compiler’s “incremental compilation” feature. The short version is that it fixed a huge amount of known bugs, but in particular, “over-analysis” problems (where an incremental update did more work than should be necessary, sometimes by a big margin) should finally be all but eliminated—making incremental compilation significantly faster in many cases! If you’ve not already, consider &lt;a href=&quot;https://ziglang.org/download/0.15.1/release-notes.html#Incremental-Compilation&quot; target=&quot;_blank&quot;&gt;trying out incremental compilation&lt;/a&gt;: it really is a lovely development experience. This is for sure the improvement which excites me the most, and a large part of what motivated this change to begin with.&lt;/p&gt;&lt;p&gt;There are a bunch more changes that come with this PR—dozens of bugfixes, some small language changes (mostly fairly niche), and compiler performance improvements. It’s far too much to list here, but if you’re interested in reading more about it, you can take a look at &lt;a href=&quot;https://codeberg.org/ziglang/zig/pulls/31403&quot; target=&quot;_blank&quot;&gt;the PR&lt;/a&gt; on Codeberg—and of course, if you encounter any bugs, please do open an issue. Happy hacking!&lt;/p&gt;&lt;/div&gt;</description>
    <link>https://ziglang.org/devlog/2026/#2026-03-10</link>
    <pubDate>Tue, 10 Mar 2026 00:00:00 +0000</pubDate>
    <guid>https://ziglang.org/devlog/2026/#2026-03-10</guid>
   </item>
  
   <item>
    <title>io_uring and Grand Central Dispatch std.Io implementations landed
</title>
    <description>&lt;div id=&quot;2026-02-13&quot;&gt;&lt;h1&gt;&lt;a class=&quot;&quot; href=&quot;#2026-02-13&quot;&gt;io_uring and Grand Central Dispatch std.Io implementations landed&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;Author: Andrew Kelley&lt;/p&gt;&lt;p&gt;As we approach the end of the 0.16.0 release cycle, Jacob has been hard at work, bringing &lt;code&gt;std.Io.Evented&lt;/code&gt; up to speed with all the latest API changes:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://codeberg.org/ziglang/zig/pulls/31158&quot; target=&quot;_blank&quot;&gt;io_uring implementation&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://codeberg.org/ziglang/zig/pulls/31198&quot; target=&quot;_blank&quot;&gt;Grand Central Dispatch implementation&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Both of these are based on userspace stack switching, sometimes called “fibers”, “stackful coroutines”, or “green threads”.&lt;/p&gt;&lt;p&gt;They are now &lt;strong&gt;available to tinker with&lt;/strong&gt;, by constructing one’s application using &lt;code&gt;std.Io.Evented&lt;/code&gt;. They should be considered &lt;strong&gt;experimental&lt;/strong&gt; because there is important followup work to be done before they can be used reliably and robustly:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://codeberg.org/ziglang/zig/issues/31199&quot; target=&quot;_blank&quot;&gt;better error handling&lt;/a&gt;&lt;/li&gt;&lt;li&gt;remove the logging&lt;/li&gt;&lt;li&gt;diagnose the unexpected performance degradation when using &lt;code&gt;IoMode.evented&lt;/code&gt; for the compiler&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://codeberg.org/ziglang/zig/issues/31200&quot; target=&quot;_blank&quot;&gt;a couple functions still unimplemented&lt;/a&gt;&lt;/li&gt;&lt;li&gt;more test coverage is needed&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/ziglang/zig/issues/157&quot; target=&quot;_blank&quot;&gt;builtin function to tell you the maximum stack size of a given function&lt;/a&gt; to make these implementations practical to use when overcommit is off.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;With those caveats in mind, it seems we are indeed reaching the Promised Land, where Zig code can have Io implementations effortlessly swapped out:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Init&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Minimal&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;debug_allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;heap&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;DebugAllocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;debug_allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;threaded&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Threaded&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;argv0&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;environ&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;environ&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;threaded&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;io&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;threaded&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Io&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeStreamingAll&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Hello, World!&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$ strace ./hello_threaded
execve(&amp;quot;./hello_threaded&amp;quot;, [&amp;quot;./hello_threaded&amp;quot;], 0x7ffc1da88b20 /* 98 vars */) = 0
mmap(NULL, 262207, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f583f338000
arch_prctl(ARCH_SET_FS, 0x7f583f378018) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
prlimit64(0, RLIMIT_STACK, {rlim_cur=16384*1024, rlim_max=RLIM64_INFINITY}, NULL) = 0
sigaltstack({ss_sp=0x7f583f338000, ss_flags=0, ss_size=262144}, NULL) = 0
sched_getaffinity(0, 128, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31]) = 8
rt_sigaction(SIGIO, {sa_handler=0x1019d90, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x10328c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGPIPE, {sa_handler=0x1019d90, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x10328c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
writev(1, [{iov_base=&amp;quot;Hello, World!\n&amp;quot;, iov_len=14}], 1Hello, World!
) = 14
rt_sigaction(SIGIO, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x10328c0}, NULL, 8) = 0
rt_sigaction(SIGPIPE, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x10328c0}, NULL, 8) = 0
exit_group(0)                           = ?
+++ exited with 0 +++
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Swapping out only the I/O implementation:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Init&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Minimal&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;debug_allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;heap&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;DebugAllocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;debug_allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;evented&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Evented&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;evented&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;argv0&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;environ&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;environ&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;backing_allocator_needs_mutex&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;evented&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;io&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;evented&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Io&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeStreamingAll&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Hello, World!&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;execve(&amp;quot;./hello_evented&amp;quot;, [&amp;quot;./hello_evented&amp;quot;], 0x7fff368894f0 /* 98 vars */) = 0
mmap(NULL, 262215, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f70a4c28000
arch_prctl(ARCH_SET_FS, 0x7f70a4c68020) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
prlimit64(0, RLIMIT_STACK, {rlim_cur=16384*1024, rlim_max=RLIM64_INFINITY}, NULL) = 0
sigaltstack({ss_sp=0x7f70a4c28008, ss_flags=0, ss_size=262144}, NULL) = 0
sched_getaffinity(0, 128, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31]) = 8
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f70a4c27000
mmap(0x7f70a4c28000, 548864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f70a4ba1000
io_uring_setup(64, {flags=IORING_SETUP_COOP_TASKRUN|IORING_SETUP_SINGLE_ISSUER, sq_thread_cpu=0, sq_thread_idle=1000, sq_entries=64, cq_entries=128, features=IORING_FEAT_SINGLE_MMAP|IORING_FEAT_NODROP|IORING_FEAT_SUBMIT_STABLE|IORING_FEAT_RW_CUR_POS|IORING_FEAT_CUR_PERSONALITY|IORING_FEAT_FAST_POLL|IORING_FEAT_POLL_32BITS|IORING_FEAT_SQPOLL_NONFIXED|IORING_FEAT_EXT_ARG|IORING_FEAT_NATIVE_WORKERS|IORING_FEAT_RSRC_TAGS|IORING_FEAT_CQE_SKIP|IORING_FEAT_LINKED_FILE|IORING_FEAT_REG_REG_RING|IORING_FEAT_RECVSEND_BUNDLE|IORING_FEAT_MIN_TIMEOUT|IORING_FEAT_RW_ATTR|IORING_FEAT_NO_IOWAIT, sq_off={head=0, tail=4, ring_mask=16, ring_entries=24, flags=36, dropped=32, array=2112, user_addr=0}, cq_off={head=8, tail=12, ring_mask=20, ring_entries=28, overflow=44, cqes=64, flags=40, user_addr=0}}) = 3
mmap(NULL, 2368, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_POPULATE, 3, 0) = 0x7f70a4ba0000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_POPULATE, 3, 0x10000000) = 0x7f70a4b9f000
io_uring_enter(3, 1, 1, IORING_ENTER_GETEVENTS, NULL, 8Hello, World!
) = 1
io_uring_enter(3, 1, 1, IORING_ENTER_GETEVENTS, NULL, 8) = 1
munmap(0x7f70a4b9f000, 4096)            = 0
munmap(0x7f70a4ba0000, 2368)            = 0
close(3)                                = 0
munmap(0x7f70a4ba1000, 548864)          = 0
exit_group(0)                           = ?
+++ exited with 0 +++
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Key point here being that the &lt;code&gt;app&lt;/code&gt; function is identical between those two snippets.&lt;/p&gt;&lt;p&gt;Moving beyond Hello World, the Zig compiler itself works fine using &lt;code&gt;std.Io.Evented&lt;/code&gt;, both with io_uring and with GCD, but as mentioned above, there is a not-yet-diagnosed performance degradation when doing so.&lt;/p&gt;&lt;p&gt;Happy hacking,&lt;/p&gt;&lt;p&gt;Andrew&lt;/p&gt;&lt;/div&gt;</description>
    <link>https://ziglang.org/devlog/2026/#2026-02-13</link>
    <pubDate>Fri, 13 Feb 2026 00:00:00 +0000</pubDate>
    <guid>https://ziglang.org/devlog/2026/#2026-02-13</guid>
   </item>
  
   <item>
    <title>Two Package Management Workflow Enhancements
</title>
    <description>&lt;div id=&quot;2026-02-06&quot;&gt;&lt;h1&gt;&lt;a class=&quot;&quot; href=&quot;#2026-02-06&quot;&gt;Two Package Management Workflow Enhancements&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;Author: Andrew Kelley&lt;/p&gt;&lt;p&gt;If you have a Zig project with dependencies, two big changes just landed which I think you will be interested to learn about.&lt;/p&gt;&lt;p&gt;Fetched packages are now stored &lt;em&gt;locally&lt;/em&gt; in the &lt;code&gt;zig-pkg&lt;/code&gt; directory of the project root (next to your &lt;code&gt;build.zig&lt;/code&gt; file).&lt;/p&gt;&lt;p&gt;For example here are a few results from &lt;a href=&quot;https://codeberg.org/awebo-chat/awebo&quot; target=&quot;_blank&quot;&gt;awebo&lt;/a&gt; after running &lt;code&gt;zig build&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ du -sh zig-pkg/*
13M    freetype-2.14.1-alzUkTyBqgBwke4Jsot997WYSpl207Ij9oO-2QOvGrOi
20K    opus-0.0.2-vuF-cMAkAADVsm707MYCtPmqmRs0gzg84Sz0qGbb5E3w
4.3M   pulseaudio-16.1.1-9-mk_62MZkNwBaFwiZ7ZVrYRIf_3dTqqJR5PbMRCJzSuLw
5.2M   uucode-0.1.0-ZZjBPvtWUACf5dqD_f9I37VGFsN24436CuceC5pTJ25n
728K   vaxis-0.5.1-BWNV_AxECQCj3p4Hcv4U3Yo1WMUJ7Z2FUj0UkpuJGxQQ
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It is highly recommended to add this directory to the project-local source control ignore file (e.g. &lt;code&gt;.gitignore&lt;/code&gt;). However, by being outside of &lt;code&gt;.zig-cache&lt;/code&gt;, it provides the possibility of distributing self-contained source tarballs, which contain all dependencies and therefore can be used to build offline, or for archival purposes.&lt;/p&gt;&lt;p&gt;Meanwhile, an &lt;em&gt;additional&lt;/em&gt; copy of the dependency is cached globally. After filtering out all the unused files based on the &lt;code&gt;paths&lt;/code&gt; filter, the contents are recompressed:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ du -sh ~/.cache/zig/p/*
2.4M    freetype-2.14.1-alzUkTyBqgBwke4Jsot997WYSpl207Ij9oO-2QOvGrOi.tar.gz
4.0K    opus-0.0.2-vuF-cMAkAADVsm707MYCtPmqmRs0gzg84Sz0qGbb5E3w.tar.gz
636K    pulseaudio-16.1.1-9-mk_62MZkNwBaFwiZ7ZVrYRIf_3dTqqJR5PbMRCJzSuLw.tar.gz
880K    uucode-0.1.0-ZZjBPvtWUACf5dqD_f9I37VGFsN24436CuceC5pTJ25n.tar.gz
120K    vaxis-0.5.1-BWNV_BFECQBbXeTeFd48uTJRjD5a-KD6kPuKanzzVB01.tar.gz
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The motivation for this change is to make it easier to tinker. Go ahead and edit those files, see what happens. Swap out your package directory with a git clone. Grep your dependencies all together. Configure your IDE to auto-complete based on the &lt;code&gt;zig-pkg&lt;/code&gt; directory. &lt;a href=&quot;https://codeberg.org/awebo-chat/awebo/issues/61&quot; target=&quot;_blank&quot;&gt;Run baobab on your dependency tree&lt;/a&gt;. Furthermore, by having the global cache have compressed files instead makes it easier to share that cached data between computers. In the future, &lt;a href=&quot;https://github.com/ziglang/zig/issues/23236&quot; target=&quot;_blank&quot;&gt;it is planned to support peer-to-peer torrenting of dependency trees&lt;/a&gt;. By recompressing packages into a canonical form, this will allow peers to share Zig packages with minimal bandwidth. I love this idea because it simultaneously provides resilience to network outages, as well as a popularity contest. Find out which open source packages are popular based on number of seeders!&lt;/p&gt;&lt;p&gt;The second change here is the addition of the &lt;code&gt;--fork&lt;/code&gt; flag to &lt;code&gt;zig build&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;In retrospect, it seems so obvious, I don’t know why I didn’t think of it since the beginning. It looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;zig build --fork=[path]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is a &lt;strong&gt;project override&lt;/strong&gt; option. Given a path to a source checkout of a project, all packages matching that project across the entire dependency tree will be overridden.&lt;/p&gt;&lt;p&gt;Thanks to the fact that package content hashes include name and fingerprint, &lt;strong&gt;this resolves before the package is potentially fetched&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;This is an easy way to temporarily use one or more forks which are in entirely separate directories. You can iterate on your entire dependency tree until everything is working, while using comfortably the development environment and source control of the dependency projects.&lt;/p&gt;&lt;p&gt;The fact that it is a CLI flag makes it appropriately ephemeral. The moment you drop the flags, you’re back to using your pristine, fetched dependency tree.&lt;/p&gt;&lt;p&gt;If the project does not match, an error occurs, preventing confusion:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ zig build --fork=/home/andy/dev/mime
error: fork /home/andy/dev/mime matched no mime packages
$
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If the project does match, you get a reminder that you are using a fork, preventing confusion:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ zig build --fork=/home/andy/dev/dvui
info: fork /home/andy/dev/dvui matched 1 (dvui) packages
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This functionality is intended to enhance the workflow of dealing with ecosystem breakage. I already tried it a bit and found it to be quite pleasant to work with. The new workflow goes like this:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Fail to build from source due to ecosystem breakage.&lt;/li&gt;&lt;li&gt;Tinker with &lt;code&gt;--fork&lt;/code&gt; until your project works again. During this time you can use the actual upstream source control, test suite, &lt;code&gt;zig build test --watch -fincremental&lt;/code&gt;, etc.&lt;/li&gt;&lt;li&gt;Now you have a new option: be selfish and just keep working on your own stuff, or you can proceed to submit your patches upstream.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;…and you can probably skip the step where you switch your &lt;code&gt;build.zig.zon&lt;/code&gt; to your fork unless you expect upstream to take a long time to merge your fixes.&lt;/p&gt;&lt;/div&gt;</description>
    <link>https://ziglang.org/devlog/2026/#2026-02-06</link>
    <pubDate>Fri, 06 Feb 2026 00:00:00 +0000</pubDate>
    <guid>https://ziglang.org/devlog/2026/#2026-02-06</guid>
   </item>
  
   <item>
    <title>Bypassing Kernel32.dll for Fun and Nonprofit
</title>
    <description>&lt;div id=&quot;2026-02-03&quot;&gt;&lt;h1&gt;&lt;a class=&quot;&quot; href=&quot;#2026-02-03&quot;&gt;Bypassing Kernel32.dll for Fun and Nonprofit&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;Author: Andrew Kelley&lt;/p&gt;&lt;p&gt;The Windows operating system provides a large ABI surface area for doing things in the kernel. However, not all ABIs are created equally. As Casey Muratori points out in his lecture, &lt;a href=&quot;https://www.youtube.com/watch?v=5IUj1EZwpJY&quot; target=&quot;_blank&quot;&gt;The Only Unbreakable Law&lt;/a&gt;, the organizational structure of software development teams has a direct impact on the structure of the software they produce.&lt;/p&gt;&lt;p&gt;The DLLs on Windows are organized into a heirarchy, with some of the APIs being high-level wrappers around lower-level ones. For example, whenever you call functions of &lt;code&gt;kernel32.dll&lt;/code&gt;, ultimately, the actual work is done by &lt;code&gt;ntdll.dll&lt;/code&gt;. You can observe this directly by using ProcMon.exe and examining stack traces.&lt;/p&gt;&lt;p&gt;What we’ve learned empirically is that the ntdll APIs are generally well-engineered, reasonable, and powerful, but the kernel32 wrappers introduce unnecessary heap allocations, additional failure modes, unintentional CPU usage, and bloat.&lt;/p&gt;&lt;p&gt;This is why the Zig standard library policy is to &lt;a href=&quot;https://codeberg.org/ziglang/zig/issues/31131&quot; target=&quot;_blank&quot;&gt;Prefer the Native API over Win32&lt;/a&gt;. We’re not quite there yet - we have plenty of calls into kernel32 remaining - but we’ve taken great strides recently. I’ll give you two examples.&lt;/p&gt;&lt;h2&gt;Example 1: Entropy&lt;/h2&gt;&lt;p&gt;According to the official documentation, Windows does not have a straightforward way to get random bytes.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/rust-random/rand/issues/111&quot; target=&quot;_blank&quot;&gt;Many projects including Chromium, boringssl, Firefox, and Rust&lt;/a&gt; call &lt;code&gt;SystemFunction036&lt;/code&gt; from &lt;code&gt;advapi32.dll&lt;/code&gt; because it worked on versions older than Windows 8.&lt;/p&gt;&lt;p&gt;Unfortunately, starting with Windows 8, the first time you call this function, it dynamically loads &lt;code&gt;bcryptprimitives.dll&lt;/code&gt; and calls &lt;a href=&quot;https://learn.microsoft.com/en-us/windows/win32/seccng/processprng&quot; target=&quot;_blank&quot;&gt;ProcessPrng&lt;/a&gt;. If loading the DLL fails (for example due to an overloaded system, which we have observed on Zig CI several times), it returns error 38 (from a function that has &lt;code&gt;void&lt;/code&gt; return type and is documented to never fail).&lt;/p&gt;&lt;p&gt;The first thing &lt;code&gt;ProcessPrng&lt;/code&gt; does is heap allocate a small, constant number of bytes. If this fails it returns &lt;code&gt;NO_MEMORY&lt;/code&gt; in a &lt;code&gt;BOOL&lt;/code&gt; (documented behavior is to never fail, and always return &lt;code&gt;TRUE&lt;/code&gt;).&lt;/p&gt;&lt;p&gt;&lt;code&gt;bcryptprimitives.dll&lt;/code&gt; apparently also runs a test suite every time you load it.&lt;/p&gt;&lt;p&gt;All that &lt;code&gt;ProcessPrng&lt;/code&gt; is &lt;em&gt;really&lt;/em&gt; doing is &lt;code&gt;NtOpenFile&lt;/code&gt; on &lt;code&gt;&amp;quot;\\Device\\CNG&amp;quot;&lt;/code&gt; and reading 48 bytes with &lt;code&gt;NtDeviceIoControlFile&lt;/code&gt; to get a seed, and then initializing a per-CPU AES-based CSPRNG.&lt;/p&gt;&lt;p&gt;So the dependency on &lt;code&gt;bcryptprimitives.dll&lt;/code&gt; and &lt;code&gt;advapi32.dll&lt;/code&gt; can both be avoided, and the nondeterministic failure and latencies on first RNG read can also be avoided.&lt;/p&gt;&lt;h2&gt;Example 2: NtReadFile and NtWriteFile&lt;/h2&gt;&lt;p&gt;&lt;code&gt;ReadFile&lt;/code&gt; looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;kernel32&amp;quot;&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;ReadFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;hFile&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;HANDLE&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;lpBuffer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;LPVOID&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;nNumberOfBytesToRead&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;DWORD&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;lpNumberOfBytesRead&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;DWORD&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;lpOverlapped&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;OVERLAPPED&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;callconv&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;winapi&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;BOOL&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;NtReadFile&lt;/code&gt; looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;ntdll&amp;quot;&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;NtReadFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;FileHandle&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;HANDLE&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;Event&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;HANDLE&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ApcRoutine&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;IO_APC_ROUTINE&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ApcContext&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;IoStatusBlock&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;IO_STATUS_BLOCK&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;Buffer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ULONG&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ByteOffset&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;LARGE_INTEGER&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ULONG&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;callconv&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;winapi&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;NTSTATUS&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a reminder, &lt;em&gt;the above function is implemented by calling the below function&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Already we can see some nice things about using the lower level API. For instance, the &lt;em&gt;real&lt;/em&gt; API simply gives us the error code as the return value, while the kernel32 wrapper hides the status code somewhere, returns a &lt;code&gt;BOOL&lt;/code&gt; and then requires you to call &lt;code&gt;GetLastError&lt;/code&gt; to find out what went wrong. Imagine! Returning a value from a function 🌈&lt;/p&gt;&lt;p&gt;Furthermore, &lt;code&gt;OVERLAPPED&lt;/code&gt; is a fake type. The Windows kernel doesn’t actually know or care about it at all! The actual primitives here are events, APCs, and &lt;code&gt;IO_STATUS_BLOCK&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;If you have a synchronous file handle, then &lt;code&gt;Event&lt;/code&gt; and &lt;code&gt;ApcRoutine&lt;/code&gt; must be &lt;code&gt;null&lt;/code&gt;. You get the answer in the &lt;code&gt;IO_STATUS_BLOCK&lt;/code&gt; immediately. If you pass an APC routine here then some old bitrotted 32-bit code runs and you get garbage results.&lt;/p&gt;&lt;p&gt;On the other hand if you have an asynchronous file handle, then you need to either use an &lt;code&gt;Event&lt;/code&gt; or an &lt;code&gt;ApcRoutine&lt;/code&gt;. &lt;code&gt;kernel32.dll&lt;/code&gt; uses events, which means that it’s doing extra, unnecessary resource allocation and management just to read from a file. Instead, Zig now passes an APC routine and then calls &lt;code&gt;NtDelayExecution&lt;/code&gt;. This integrates seamlessly with cancelation, making it possible to cancel tasks while they perform file I/O, regardless of whether the file was opened in synchronous mode or asynchronous mode.&lt;/p&gt;&lt;p&gt;For a deeper dive into this topic, please refer to this issue:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://codeberg.org/ziglang/zig/issues/31131&quot; target=&quot;_blank&quot;&gt;Windows: Prefer the Native API over Win32&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;</description>
    <link>https://ziglang.org/devlog/2026/#2026-02-03</link>
    <pubDate>Tue, 03 Feb 2026 00:00:00 +0000</pubDate>
    <guid>https://ziglang.org/devlog/2026/#2026-02-03</guid>
   </item>
  
   <item>
    <title>zig libc
</title>
    <description>&lt;div id=&quot;2026-01-31&quot;&gt;&lt;h1&gt;&lt;a class=&quot;&quot; href=&quot;#2026-01-31&quot;&gt;zig libc&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;Author: Andrew Kelley&lt;/p&gt;&lt;p&gt;Over the past month or so, several enterprising contributors have taken an interest in the &lt;a href=&quot;https://codeberg.org/ziglang/zig/issues/30978&quot; target=&quot;_blank&quot;&gt;zig libc subproject&lt;/a&gt;. The idea here is to incrementally delete redundant code, by providing libc functions as Zig standard library wrappers rather than as vendored C source files. In many cases, these functions are one-to-one mappings, such as &lt;code&gt;memcpy&lt;/code&gt; or &lt;code&gt;atan2&lt;/code&gt;, or trivially wrap a generic function, like &lt;code&gt;strnlen&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;strnlen&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;c_char&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;callconv&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;findScalar&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@ptrCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_operator&quot;&gt;orelse&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So far, roughly 250 C source files have been deleted from the Zig repository, with 2032 remaining.&lt;/p&gt;&lt;p&gt;With each function that makes the transition, Zig gains independence from third party projects and from the C programming language, compilation speed improves, Zig’s installation size is simplified and reduced, and user applications which statically link libc enjoy reduced binary size.&lt;/p&gt;&lt;p&gt;Additionally, a &lt;a href=&quot;https://codeberg.org/ziglang/zig/pulls/31037&quot; target=&quot;_blank&quot;&gt;recent enhancement&lt;/a&gt; now makes zig libc share the Zig Compilation Unit with other Zig code rather than being a separate static archive, linked together later. This is one of the advantages of Zig having an integrated compiler and linker. When the exported libc functions share the ZCU, redundant code is eliminated because functions can be optimized together. It’s kind of like enabling LTO (Link-Time Optimization) across the libc boundary, except it’s done properly in the frontend instead of too late, in the linker.&lt;/p&gt;&lt;p&gt;Furthermore, when this work is combined with the recent &lt;a href=&quot;https://codeberg.org/ziglang/zig/issues/30150&quot; target=&quot;_blank&quot;&gt;std.Io changes&lt;/a&gt;, there is potential for users to seamlessly control how libc performs I/O - for example forcing all calls to &lt;code&gt;read&lt;/code&gt; and &lt;code&gt;write&lt;/code&gt; to participate in an io_uring event loop, even though that code was not written with such use case in mind. Or, &lt;a href=&quot;https://codeberg.org/ziglang/zig/pulls/30788&quot; target=&quot;_blank&quot;&gt;resource leak detection&lt;/a&gt; could be enabled for third-party C code. For now this is only a vaporware idea which has not been experimented with, but the idea intrigues me.&lt;/p&gt;&lt;p&gt;Big thanks to Szabolcs Nagy for &lt;a href=&quot;https://wiki.musl-libc.org/libc-test.html&quot; target=&quot;_blank&quot;&gt;libc-test&lt;/a&gt;. This project has been a huge help in making sure that we don’t regress any math functions.&lt;/p&gt;&lt;p&gt;As a reminder to our users, now that Zig is transitioning to being the static libc provider, if you encounter issues with the musl, mingw-w64, or wasi-libc libc functionality provided by Zig, &lt;strong&gt;please file bug reports in Zig first&lt;/strong&gt; so we don’t annoy maintainers for bugs that are in Zig, and no longer vendored by independent libc implementation projects.&lt;/p&gt;&lt;p&gt;The very same day I sat at home writing this devlog like a coward, less than five miles away, &lt;a href=&quot;https://www.kptv.com/2026/01/31/live-labor-unions-rally-march-portland-ice-facility-protest/&quot; target=&quot;_blank&quot;&gt;armed forces who are in my city against the will of our elected officials shot tear gas, unprovoked, at peaceful protestors&lt;/a&gt;. Next time I hope to have the courage to join my neighbors, and I hope to not get shot like &lt;a href=&quot;https://en.wikipedia.org/wiki/Killing_of_Alex_Pretti&quot; target=&quot;_blank&quot;&gt;Alex Pretti&lt;/a&gt; and &lt;a href=&quot;https://en.wikipedia.org/wiki/Killing_of_Ren%C3%A9e_Good&quot; target=&quot;_blank&quot;&gt;Renée Good&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;</description>
    <link>https://ziglang.org/devlog/2026/#2026-01-31</link>
    <pubDate>Sat, 31 Jan 2026 00:00:00 +0000</pubDate>
    <guid>https://ziglang.org/devlog/2026/#2026-01-31</guid>
   </item>
  
 </channel>
</rss>
