<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>ziglang.org</title>
  <subtitle>Browse aymeric&#39;s, an independent, searchable archive of readable snapshots from followed feeds, preserved in Git with aggr.</subtitle>
  <id>https://aggr.aymericbeaumet.com/sources/ziglang.org/</id>
  <link rel="alternate" type="text/html" href="https://aggr.aymericbeaumet.com/sources/ziglang.org/"/>
  <link rel="self" type="application/atom+xml" href="https://aggr.aymericbeaumet.com/sources/ziglang.org/atom.xml"/>
  <updated>2026-11-04T10:57:35+00:00</updated>
  <author>
    <name>aymeric&#39;s</name>
  </author>
  <generator version="2.0.0" uri="https://github.com/aymericbeaumet/aggr">aggr</generator>
  <entry>
    <id>urn:aggr:item:b6b3764aeacaa86c0db297e5259133742f11f899</id>
    <title type="text">Zig 0.17.1 Released</title>
    <link rel="alternate" type="text/html" href="https://aggr.aymericbeaumet.com/items/lobste-rs/2026-11-04-zig-0-17-1-released/"/>
    <link rel="via" type="text/html" href="https://ziglang.org/news/0.17.1-released/"/>
    <published>2026-11-04T10:57:35+00:00</published>
    <updated>2026-11-04T10:57:35+00:00</updated>
    <author>
      <name>ziglang.org via FedericoSchonborn</name>
    </author>
    <category term="news"/>
    <category term="release"/>
    <category term="zig"/>
    <source>
      <title>Lobsters: Top Stories of the Past Week</title>
    </source>
    <summary type="text">Comments</summary>
    <content type="html">&lt;p&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/news/&quot;&gt;← Back to &lt;strong&gt;News&lt;/strong&gt; page&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;November 03, 2026&lt;/h3&gt;
&lt;p&gt;This is a bug fix release addressing more than &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/issues?q=&amp;amp;milestone=153840&quot;&gt;57 issues&lt;/a&gt; reported after the 0.17.0 release, with a particular focus on regressions and upgrade blockers. Most users who were unable to upgrade to 0.17.0 should be able to upgrade to 0.17.1.&lt;/p&gt;
&lt;p&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/download/#release-0.17.1&quot;&gt;Download &amp;amp; Documentation&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>urn:aggr:item:46736b49bb312400188fddd03bc5e0107cea25b6</id>
    <title type="text">Partial Operator Precedence</title>
    <link rel="alternate" type="text/html" href="https://aggr.aymericbeaumet.com/items/lobste-rs/2026-10-25-partial-operator-precedence/"/>
    <link rel="via" type="text/html" href="https://ziglang.org/devlog/2026/#2026-10-24"/>
    <published>2026-10-25T14:18:21+00:00</published>
    <updated>2026-10-25T14:18:21+00:00</updated>
    <author>
      <name>ziglang.org via liberty</name>
    </author>
    <category term="news"/>
    <category term="zig"/>
    <source>
      <title>Lobsters: Top Stories of the Past Week</title>
    </source>
    <summary type="text">Comments</summary>
    <content type="html">&lt;p&gt;This page contains a curated list of recent changes to main branch Zig.&lt;/p&gt;
&lt;p&gt;This page contains entries for the year 2026. Other years are available in &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/&quot;&gt;the Devlog archive page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;October 24, 2026&lt;/p&gt;
&lt;h2&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/2026/#2026-10-24&quot;&gt;Partial Operator Precedence&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Author: Ryan Liptak&lt;/p&gt;
&lt;p&gt;As of yesterday, the second oldest open proposal for the Zig language was &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/ziglang/zig/issues/114&quot;&gt;issue #114: require parentheses sometimes to disambiguate confusing operator precedence&lt;/a&gt;, opened February 8, 2016. Ten years later, that proposal &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/pulls/30160&quot;&gt;has been implemented&lt;/a&gt; in the master branch version of Zig thanks to contributor &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://cmdrzero.github.io/&quot;&gt;CMDRZero&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This means that some combinations of operators no longer have a defined precedence, and for those that don’t, the compiler will now require parentheses:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;const a = x orelse y == z;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;JavaScript&quot;&gt;&lt;span class=&quot;syntax-source syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;zig&lt;/span&gt;:&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;1&lt;/span&gt;:&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;22&lt;/span&gt;: &lt;span class=&quot;syntax-entity syntax-name syntax-label syntax-js&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-js&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;ambiguous&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;operator&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;precedence&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-with syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-with syntax-js&quot;&gt;with&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;operators&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;orelse&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-comparison syntax-js&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-spread syntax-js&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;parentheses&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;disambiguate&lt;/span&gt;
&lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;orelse&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-comparison syntax-js&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
                     &lt;span class=&quot;syntax-keyword syntax-operator syntax-bitwise syntax-js&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-bitwise syntax-js&quot;&gt;~&lt;/span&gt;
&lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;zig&lt;/span&gt;:&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;1&lt;/span&gt;:&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;13&lt;/span&gt;: &lt;span class=&quot;syntax-entity syntax-name syntax-label syntax-js&quot;&gt;note&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-js&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;previous&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;ambiguous&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;operator&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;here&lt;/span&gt;
&lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;orelse&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-comparison syntax-js&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;syntax-keyword syntax-operator syntax-bitwise syntax-js&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-bitwise syntax-js&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-bitwise syntax-js&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-bitwise syntax-js&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-bitwise syntax-js&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-bitwise syntax-js&quot;&gt;~&lt;/span&gt;
&lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;zig&lt;/span&gt;:&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;1&lt;/span&gt;:&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;22&lt;/span&gt;: &lt;span class=&quot;syntax-entity syntax-name syntax-label syntax-js&quot;&gt;note&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-js&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;zig&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;0.17&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-language syntax-this syntax-js&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;was&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;evaluated&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-control syntax-import-export syntax-js&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-spread syntax-js&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;orelse&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-comparison syntax-js&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-spread syntax-js&quot;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, common cases can remain parenthesis-free:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;const a = x + y * z;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The idea behind this is to reduce the number of rules a programmer needs to know when reading and writing Zig code. For example, no matter how experienced you are with Zig, it’s unlikely that you’d be able to explain the evaluation order of the following expression without looking up the precedence rules:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;a &amp;amp; b + c * d &amp;gt;&amp;gt; e | f orelse g() catch h + i == j or k and l
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the now-required parentheses added (while maintaining the same evaluation order as the Zig 0.17.x precedence rules), that expression would look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;((((a &amp;amp; ((b + c * d) &amp;gt;&amp;gt; e)) | f) orelse g()) catch (h + i)) == j or (k and l);
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Still quite hairy, and not something I’d like to see in the wild, but nonetheless it’s understandable without knowing any precedence rules beyond arithmetic and comparison. Outside of this contrived example, though, the expressions that will now require parentheses are relatively rare (353 lines needed changes out of the million+ lines of code in the Zig codebase).&lt;/p&gt;
&lt;h2&gt;What you need to know&lt;/h2&gt;
&lt;p&gt;In practice, going forward, you will only need to remember the rules around operator combinations that &lt;em&gt;still have&lt;/em&gt; a defined/unambiguous precedence. For example, when reading or writing code involving arithmetic operators, you’ll only need to remember the following precedence table:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;* / *% *| %
+ - +% -% +| -|
== != &amp;lt; &amp;gt; &amp;lt;= &amp;gt;=
and or
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You might notice that there isn’t anything too surprising there, and that lack of surprise was a (subjective) guiding principle for what should and should not require parentheses. As an example, while &lt;code&gt;%&lt;/code&gt; has unambiguous precedence with regards to addition/subtraction operators, parentheses must be used when mixing &lt;code&gt;%&lt;/code&gt; with multiplication/division operators, and with itself. However, this, and other ambiguous operator combinations, aren’t something you’ll need to commit to memory. Any (future) code you read will already have parentheses to disambiguate, and for any code you write, the compiler will let you know when you need parentheses.&lt;/p&gt;
&lt;p&gt;For the full explanation, and to see the relevant precedence tables pertaining to other operators, see &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/documentation/master/#Precedence&quot;&gt;the updated Precedence section of the language reference&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Upgrading existing code&lt;/h2&gt;
&lt;p&gt;There are two possible approaches here:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Manually fix each “ambiguous operator precedence” error as they are surfaced by the compiler (this might be a good opportunity to try out &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/download/0.17.0/release-notes.html#Incremental-Compilation&quot;&gt;incremental compilation&lt;/a&gt; if it’s supported on your platform)&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;zig fmt --upgrade&lt;/code&gt; (the &lt;code&gt;--upgrade&lt;/code&gt; flag was added for this purpose). This will cause &lt;code&gt;zig fmt&lt;/code&gt; to add parentheses automatically, maintaining the evaluation order from the previous precedence rules (note: the &lt;code&gt;--upgrade&lt;/code&gt; flag will be removed after one release cycle)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;My personal recommendation would be option 1, as the process of redetermining the intended evaluation order for these uncommon precedence scenarios can occasionally serve to uncover bugs (&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/Vexu/arocc/pull/1117&quot;&gt;here’s an example of that&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;If you go with option 2, I’d still recommend perusing the diff afterwards to ensure that nothing looks unusual, or is different than you expected/intended. A potentially common example of that is something like &lt;code&gt;a orelse b() catch c&lt;/code&gt; which previously evaluated to &lt;code&gt;(a orelse b()) catch c&lt;/code&gt;, but changing that to &lt;code&gt;a orelse (b() catch c)&lt;/code&gt; likely makes more sense, even if the end result is unaffected. Also worth noting that in some scenarios, redundant parentheses will be added by &lt;code&gt;zig fmt --upgrade&lt;/code&gt; (e.g. you might see something like &lt;code&gt;a orelse ((b + c) - d)&lt;/code&gt; where the parentheses around &lt;code&gt;b + c&lt;/code&gt; are unnecessary), so avoiding that will take a bit of manual cleanup.&lt;/p&gt;
&lt;p&gt;That’s about it. I’m hopeful that this change will make bugs stemming from misremembered precedence rules much less likely, and that it will put some attention onto any of those bugs that may currently exist.&lt;/p&gt;
&lt;p&gt;Thanks again to CMDRZero for the implementation, and to Isaac Freund for help with the corresponding grammar changes.&lt;/p&gt;
&lt;p&gt;October 20, 2026&lt;/p&gt;
&lt;h2&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/2026/#2026-10-20&quot;&gt;Naked Package Metadata&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Naked packages are ones that do not include a build manifest (build.zig.zon file). This is typically due to them being maintained by third parties outside the Zig ecosystem.&lt;/p&gt;
&lt;p&gt;Until now, those package hashes looked like: &lt;code&gt;N-V-__8AAA7lSAA6p7eRmPGVeA9uHmeiJ2DX-ISiPliRJ8Y7&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This is because, without a build.zig.zon file, there was no &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;version&lt;/code&gt; to use in the package hash. Furthermore, those packages have brittle hashes because they included all fetched files without any filter, which may accidentally have included unwanted hidden files that nonetheless cause the package hash to change. Or, the package might have contained symlinks that cannot be created on a particular OS. Without a filter, such files, even if they were unneeded, caused fetching to fail.&lt;/p&gt;
&lt;p&gt;Now, Zig supports specifying &lt;code&gt;version&lt;/code&gt; and &lt;code&gt;paths&lt;/code&gt; for naked packages next to the URL. The dependency name will also be factored into the package hash, but &lt;strong&gt;only when &lt;code&gt;version&lt;/code&gt; is provided.&lt;/strong&gt; This allows users to opt in, as opposed to having the package hash change suddenly when updating Zig.&lt;/p&gt;
&lt;p&gt;Here’s an updated zlib for example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;    .dependencies = .{
        .zlib = .{
            .url = &amp;quot;https://github.com/madler/zlib/archive/refs/tags/v1.3.2.tar.gz&amp;quot;,
            .hash = &amp;quot;zlib-1.3.2-__8AANXpEADvBXGMSfhczMTZVAA-TkkE4ecoohAR7s3p&amp;quot;,
            .version = &amp;quot;1.3.2&amp;quot;,
            .paths = .{
                &amp;quot;LICENSE&amp;quot;,
                &amp;quot;adler32.c&amp;quot;,
                &amp;quot;compress.c&amp;quot;,
                &amp;quot;crc32.c&amp;quot;,
                &amp;quot;crc32.h&amp;quot;,
                &amp;quot;deflate.c&amp;quot;,
                &amp;quot;deflate.h&amp;quot;,
                &amp;quot;gzclose.c&amp;quot;,
                &amp;quot;gzguts.h&amp;quot;,
                &amp;quot;gzlib.c&amp;quot;,
                &amp;quot;gzread.c&amp;quot;,
                &amp;quot;gzwrite.c&amp;quot;,
                &amp;quot;infback.c&amp;quot;,
                &amp;quot;inffast.c&amp;quot;,
                &amp;quot;inffast.h&amp;quot;,
                &amp;quot;inffixed.h&amp;quot;,
                &amp;quot;inflate.c&amp;quot;,
                &amp;quot;inflate.h&amp;quot;,
                &amp;quot;inftrees.c&amp;quot;,
                &amp;quot;inftrees.h&amp;quot;,
                &amp;quot;trees.c&amp;quot;,
                &amp;quot;trees.h&amp;quot;,
                &amp;quot;uncompr.c&amp;quot;,
                &amp;quot;zconf.h&amp;quot;,
                &amp;quot;zlib.h&amp;quot;,
                &amp;quot;zutil.c&amp;quot;,
                &amp;quot;zutil.h&amp;quot;,
            },
        },
    },
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Before:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;4.3M    zig-pkg/N-V-__8AAI4ANwDM8MWhHTUFLKfvLE_n2NQk6mh0sFDzhTqO
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;1.2M    zig-pkg/zlib-1.3.2-__8AANXpEADvBXGMSfhczMTZVAA-TkkE4ecoohAR7s3p
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/pulls/37340&quot;&gt;Pull Request&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;October 14, 2026&lt;/p&gt;
&lt;h2&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/2026/#2026-10-14&quot;&gt;Package Hash Consistency Validation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Any time the same package (based on &lt;code&gt;fingerprint&lt;/code&gt;) appears in the dependency tree, if the semantic version compares equal, the hash must be identical, otherwise one of three things has gone wrong and the maintainer must address it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;package ownership dispute: somebody forked someone else’s package without changing the name or fingerprint, or&lt;/li&gt;
&lt;li&gt;package maintainer neglected to bump version after making changes, or&lt;/li&gt;
&lt;li&gt;dependency on unreleased changes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When this error occurs, the project maintainer should take care to understand &lt;em&gt;why&lt;/em&gt; those two (or more) packages have contradictory hash information before deciding what to do.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;andy@bark ~/d/ffmpeg (main)&amp;gt; zig build
error: contradictory hash for package with fingerprint 0x7118c1b07efea3d0 and version 0.0.0: libogg-0.0.0+1.3.7-0KP-flwMAACKAIH-iEs4gbg30ll_FQ-cW50JvLZO8VTg
error: contradictory hash for package with fingerprint 0x7118c1b07efea3d0 and version 0.0.0: libogg-0.0.0+1.3.7-0KP-foYNAAAaj0YJOwRQs7kTN-ivzRMYTjtKzr6Apelj
info: potential cause: package ownership dispute
info: potential cause: maintainer neglected to bump version after making changes
info: potential cause: dependency on unreleased changes
info: hint: use --print-tree to visualize all package versions and hashes
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;October 13, 2026&lt;/p&gt;
&lt;h2&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/2026/#2026-10-13&quot;&gt;Printing Package Tree&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There is a new &lt;code&gt;--print-tree&lt;/code&gt; CLI option to &lt;code&gt;zig build&lt;/code&gt;, that looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;andy@bark ~/d/groovebasin (main)&amp;gt; zig build --print-tree
ffmpeg ffmpeg-8.1.1-5-zT7QA_AkUgTOx4ZqOUVZsHSk9iv97BInIiubIM6ifr67
├─ libz zlib-1.3.1-1-ZZQ7ldENAAA7qJjUXP6E6xnRuV-jDL9dyoJFc_eb3zQ6
│  └─ zlib N-V-__8AAB0eQwD-0MdOEBmz7intriBReIsIDNlukNVoNu6o
├─ mbedtls mbedtls-3.6.4-E4NUR2wWAAAUSvVbho9aaU31-e4D8glu9l1VfxKezBkV (not fetched)
├─ openssl openssl-3.3.2-TC9C3Ze3ZABaKR5hc8KRnRPhTClKrKQKqTnXTUYkvmSR (not fetched)
├─ libressl libressl-4.0.0--kqV4KPTAACsSRP8mSIZmqgVa5OZjw6WEgvcftWkLu-c (not fetched)
├─ libmp3lame libmp3lame-3.100.1-7-67wlF2CxEwDWlVOMMLBNPbnDi5kE2OmH0azUHU2Y4DZY
├─ libvorbis libvorbis-0.0.0+1.3.7-1wt9j_QPAADVure94TG4ecBMLD8eIAzWd6ZxVOmBBPCu
│  ├─ libvorbis N-V-__8AAA7lSAA6p7eRmPGVeA9uHmeiJ2DX-ISiPliRJ8Y7
│  └─ libogg libogg-0.0.0+1.3.7-0KP-foYNAAAaj0YJOwRQs7kTN-ivzRMYTjtKzr6Apelj
│     └─ libogg N-V-__8AAFM3CwD6iAA1kggMPR8NHZ8VTb2zvRZ1Mt4BUfq9
├─ libogg libogg-0.0.0+1.3.7-0KP-foYNAAAaj0YJOwRQs7kTN-ivzRMYTjtKzr6Apelj
│  └─ libogg N-V-__8AAFM3CwD6iAA1kggMPR8NHZ8VTb2zvRZ1Mt4BUfq9
└─ nasm nasm-3.0.1-B_NnpQpTAAA25UxvqONakXtmj-a78PGe3xfgyDFgetb0
   ├─ nasm N-V-__8AAEAMKAFrNesgN6ZM9sxj37fq_i7UJe5nKkLmyRJI
   └─ zlib zlib-1.3.1-1-ZZQ7ldENAAA7qJjUXP6E6xnRuV-jDL9dyoJFc_eb3zQ6
      └─ zlib N-V-__8AAB0eQwD-0MdOEBmz7intriBReIsIDNlukNVoNu6o
pulseaudio pulseaudio-16.1.1-10-mk_62DNlNwCDcTJ5iGhTxeCoetuAFKE1FrYNw5AErtX-
StaticHttpFileServer StaticHttpFileServer-1.0.0-j-0gwes2AAByCgpeLBNR2hOaGVsDz9u8I6o54ft10OxU
└─ mime mime-4.0.0-zwmL--0gAACndOVlROQeDnM0chfojNDS8tpohlsBqMNy
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If a terminal is detected, it prints in color, which is a bit easier to read.&lt;/p&gt;
&lt;p&gt;This &lt;strong&gt;early exits before running configurer&lt;/strong&gt;, so that problems causing configurer compilation errors can be troubleshooted.&lt;/p&gt;
&lt;p&gt;Similarly, &lt;code&gt;--configure&lt;/code&gt; is added, which is defined to “exit after the configuration phase” which is the exact behavior that &lt;code&gt;--fetch&lt;/code&gt; used to do. &lt;code&gt;--fetch&lt;/code&gt; is changed to “Fetch all dependencies including lazy ones; exit without configuration”.&lt;/p&gt;
&lt;p&gt;October 12, 2026&lt;/p&gt;
&lt;h2&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/2026/#2026-10-12&quot;&gt;More Resilient Help Menu&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;zig build --help&lt;/code&gt; now works even when configuration fails, or when there is no build.zig file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;YAML&quot;&gt;&lt;span class=&quot;syntax-source syntax-yaml&quot;&gt;&lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-tag syntax-yaml&quot;&gt;info&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;initialize build.zig template file with &amp;quot;zig init&amp;quot;&lt;/span&gt;
&lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-tag syntax-yaml&quot;&gt;info&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;see &amp;quot;zig --help&amp;quot; for more options&lt;/span&gt;
&lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-tag syntax-yaml&quot;&gt;error&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;no build.zig file found, in the current directory or any parent directories&lt;/span&gt;
&lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-tag syntax-yaml&quot;&gt;Usage&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;zig build [steps] [options]&lt;/span&gt;

&lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-tag syntax-yaml&quot;&gt;Steps&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml&quot;&gt;:&lt;/span&gt;                    &lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;(unavailable due to build.zig compilation failure)&lt;/span&gt;
&lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-tag syntax-yaml&quot;&gt;Project-Specific Options&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;(unavailable due to build.zig compilation failure)&lt;/span&gt;

&lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-tag syntax-yaml&quot;&gt;System Integration Options&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;--search-prefix [path]       Add a path to look for binaries, libraries, headers&lt;/span&gt;
  &lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;--sysroot [path]             Set the system root directory (usually /)&lt;/span&gt;
&lt;span class=&quot;syntax-entity syntax-other syntax-document syntax-end syntax-yaml&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-tag syntax-yaml&quot;&gt;Available System Integrations&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml&quot;&gt;:&lt;/span&gt;                &lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-tag syntax-yaml&quot;&gt;Enabled&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml&quot;&gt;:&lt;/span&gt;

   &lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;(unavailable due to build.zig compilation failure)&lt;/span&gt;

&lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-tag syntax-yaml&quot;&gt;General Options&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-mapping syntax-yaml&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;-h, --help                   Print this help to stdout and exit&lt;/span&gt;
  &lt;span class=&quot;syntax-string syntax-unquoted syntax-plain syntax-out syntax-yaml&quot;&gt;-l, --list-steps             Print available steps to stdout and exit&lt;/span&gt;
&lt;span class=&quot;syntax-entity syntax-other syntax-document syntax-end syntax-yaml&quot;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;August 27, 2026&lt;/p&gt;
&lt;h2&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/2026/#2026-08-27&quot;&gt;Pointer Stability for ArrayLists&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Author: Robbie Lyman&lt;/p&gt;
&lt;p&gt;Pointer Stability Locks were &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/ziglang/zig/pull/17719&quot;&gt;added to &lt;code&gt;std&lt;/code&gt;’s Hash Map containers in 2024&lt;/a&gt;. A pull request initially opened by &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/emar-kar&quot;&gt;Leo Emar-Kar&lt;/a&gt; in 2025 now brings this technique for ensuring memory safety to &lt;code&gt;std.ArrayList&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To make use of this in your code, add a call to &lt;code&gt;lockPointers()&lt;/code&gt; when you first store a pointer to an element or a slice of elements backed by the &lt;code&gt;ArrayList&lt;/code&gt;, and call &lt;code&gt;unlockPointers()&lt;/code&gt; when those pointers are no longer needed.&lt;/p&gt;
&lt;p&gt;Here’s a somewhat contrived example. Let’s suppose we are managing two &lt;code&gt;ArrayLists&lt;/code&gt;, say one of which is holding in memory the contents of some input, while the other is storing chunks of interest; maybe each line. Here’s a version of this process which has a bug; see if you can spot it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;const std = @import(&amp;quot;std&amp;quot;);

const Context = struct {
    history: std.ArrayList(u8),
    lines: std.ArrayList([]const u8),

    fn parse(ctx: *Context, allocator: std.mem.Allocator, input: []const u8) !void {
        const slice = try ctx.history.addManyAsSlice(allocator, input.len);
        @memcpy(slice, input);
        var it = std.mem.tokenizeScalar(u8, slice, &amp;#39;\n&amp;#39;);
        while (it.next()) |line| {
            try ctx.lines.append(allocator, line);
        }
    }
};
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Did you spot the bug? The problem is that elements of &lt;code&gt;Context.lines.items&lt;/code&gt; depend on the &lt;em&gt;location&lt;/em&gt; of &lt;code&gt;Context.history.items&lt;/code&gt;, but this location may &lt;em&gt;change&lt;/em&gt; if &lt;code&gt;Context.history&lt;/code&gt; needs to grow beyond its current capacity. Here’s a reproduction of the bug:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;JavaScript&quot;&gt;&lt;span class=&quot;syntax-source syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-js&quot;&gt;&amp;quot;&lt;/span&gt;Context.parse&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-js&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-block syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-js&quot;&gt;&amp;quot;&lt;/span&gt;I&amp;#39;m first!&lt;span class=&quot;syntax-constant syntax-character syntax-escape syntax-js&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-js&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;input_two&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt;
        \\&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;But&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-language syntax-this syntax-js&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;text&lt;/span&gt;
        \\&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;juuuuuuuuuuuuuuuuuuuuuuuuust&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;enough&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;that&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;it&lt;/span&gt;
        \\&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;causes&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;problem&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-logical syntax-js&quot;&gt;!&lt;/span&gt;
        \\&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;And&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;problem&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;could&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;be&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;that&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;we&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;segfault&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-logical syntax-js&quot;&gt;!&lt;/span&gt;
        \\&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;Which&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;no&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;into&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;
    &lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;ctx&lt;/span&gt;: &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;Context&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;history&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;lines&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;gpa&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;testing&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;history&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-method syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;gpa&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-method syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;gpa&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;syntax-meta syntax-try syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-trycatch syntax-js&quot;&gt;try&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-method syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;gpa&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;input&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;syntax-meta syntax-try syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-trycatch syntax-js&quot;&gt;try&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-method syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;gpa&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;input_two&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;syntax-meta syntax-try syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-trycatch syntax-js&quot;&gt;try&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;testing&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-method syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;expectEqualStrings&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-js&quot;&gt;&amp;quot;&lt;/span&gt;I&amp;#39;m first!&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-js&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-brackets syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-brackets syntax-js&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-brackets syntax-js&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If I run this code with &lt;code&gt;zig test&lt;/code&gt;, I get the following output (plus a little more).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;====== expected this output: =========
I&amp;#39;m first!␃

======== instead found this: =========
UUUUUUUUUU␃

======================================
First difference occurs on line 1:
expected:
I&amp;#39;m first!
^ (&amp;#39;\x49&amp;#39;)
found:
UUUUUUUUUU
^ (&amp;#39;\x55&amp;#39;)
1/1 blah.test.Context.parse...FAIL (TestExpectedEqual)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Not great, right? This does tell us that we &lt;em&gt;have&lt;/em&gt; a bug, but depending on your comfort debugging memory issues (and your choice of allocator, which will change how the bug manifests!), you might be lost for quite a while before you spot the fix.&lt;/p&gt;
&lt;p&gt;Since we’ve stored pointers after the first call to &lt;code&gt;parse&lt;/code&gt; in our test, what happens if we make this change?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;    try ctx.parse(gpa, input);
+   ctx.history.lockPointers();
+   defer ctx.history.unlockPointers();
    try ctx.parse(gpa, input_two);
    try std.testing.expectEqualStrings(&amp;quot;I&amp;#39;m first!&amp;quot;, ctx.lines.items[0]);
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We get a panic with a stack trace that shows us where our assumption about pointer stability was violated!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;thread 3023222 panic: reached unreachable code
/Users/robbie/bin/lib/std/debug.zig:442:14: 0x102d2506f in assert (test)
    if (!ok) unreachable; // assertion failure
             ^
/Users/robbie/bin/lib/std/debug.zig:1880:15: 0x102d31ef7 in assertUnlocked (test)
        assert(l.state == .unlocked);
              ^
/Users/robbie/bin/lib/std/array_list.zig:1348:50: 0x102e3ced7 in ensureTotalCapacityPrecise (test)
            self.pointer_stability.assertUnlocked();
                                                 ^
/Users/robbie/bin/lib/std/array_list.zig:1341:51: 0x102e3cdff in ensureTotalCapacity (test)
            return self.ensureTotalCapacityPrecise(gpa, growCapacity(new_capacity));
                                                  ^
/Users/robbie/bin/lib/std/array_list.zig:1237:41: 0x102e4e5c3 in resize (test)
            try self.ensureTotalCapacity(gpa, new_len);
                                        ^
/Users/robbie/bin/lib/std/array_list.zig:1461:28: 0x102e4e40f in addManyAsSlice (test)
            try self.resize(gpa, try addOrOom(self.items.len, n));
                           ^
/Users/robbie/src/advent-of-code/2024/blah.zig:8:51: 0x102e4dc1f in parse (test)
        const ptr = try ctx.history.addManyAsSlice(allocator, input.len);
                                                  ^
/Users/robbie/src/advent-of-code/2024/blah.zig:35:18: 0x102e4e167 in test.Context.parse (test)
    try ctx.parse(gpa, input_two);
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nice, that’s already a big help: now I can see that I should consider memory safety issues as a probable cause of my test failure in addition or instead of a logic issue. Obviously this example was somewhat contrived, but I do find myself reaching for &lt;code&gt;std.ArrayList&lt;/code&gt; as this type of backing storage in real code, so I hope you can see real-world use cases for it yourself.&lt;/p&gt;
&lt;p&gt;Before I close, I want to point out something subtle: unlike &lt;code&gt;HashMap&lt;/code&gt; and its friends, &lt;code&gt;ArrayList&lt;/code&gt; is &lt;em&gt;ordered,&lt;/em&gt; which means that operations on the list may move elements around even without moving, resizing or freeing the backing memory of the list as a whole. For example, the pointer (well, slice) returned by &lt;code&gt;addManyAsSlice(gpa, n)&lt;/code&gt; may not point to the final &lt;code&gt;n&lt;/code&gt; elements of the list if you call &lt;code&gt;orderedRemove()&lt;/code&gt; or &lt;code&gt;pop()&lt;/code&gt;. For this reason, although &lt;code&gt;orderedRemove()&lt;/code&gt; and &lt;code&gt;pop()&lt;/code&gt; never allocate, they &lt;em&gt;will&lt;/em&gt; trigger the same assertion above after a call to &lt;code&gt;lockPointers()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;June 30, 2026&lt;/p&gt;
&lt;h2&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/2026/#2026-06-30&quot;&gt;All Package Management Functionality Moved from Compiler to Build System&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Author: Andrew Kelley&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;I moved these subcommands to the maker process:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;zig build&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;zig fetch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;zig init&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;zig libc&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This means that large parts of what used to be included in the compiler executable are now shipped in source form instead, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;package fetching logic&lt;/li&gt;
&lt;li&gt;HTTP client and networking&lt;/li&gt;
&lt;li&gt;TLS (Transport Layer Security) and associated crypto&lt;/li&gt;
&lt;li&gt;Git protocol&lt;/li&gt;
&lt;li&gt;xz, gzip, zstd, flate, zip&lt;/li&gt;
&lt;li&gt;parsing, validation, and otherwise dealing with &lt;code&gt;build.zig.zon&lt;/code&gt; files&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Consequently, this functionality can now be patched without rebuilding the compiler, making it easier for users and contributors to tinker.&lt;/p&gt;
&lt;p&gt;Furthermore, it means that package management in zig now has safety checks enabled when doing networking, since the maker executable is compiled in &lt;code&gt;ReleaseSafe&lt;/code&gt; 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. &lt;em&gt;We can have AOT cake and eat JIT, too!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;My original motivation for doing this was in relation to exposing a &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/issues/35538&quot;&gt;build server protocol&lt;/a&gt; in order to unblock &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://zigtools.org/zls/&quot;&gt;ZLS&lt;/a&gt; after &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/2026/#2026-05-26&quot;&gt;maker/configurer process separation&lt;/a&gt; made breaking changes to the &lt;code&gt;--build-runner&lt;/code&gt; override flag.&lt;/p&gt;
&lt;p&gt;Originally, the process tree looked like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;zig build  (the zig compiler + package manager)
└─ builder (the user&amp;#39;s build.zig logic + build system implementation)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The process separation changeset made it look like this instead:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;zig build     (the zig compiler + package manager)
├─ configurer (the user&amp;#39;s build.zig logic)
└─ maker      (build system)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point, consider a long-running &lt;code&gt;zig build --watch&lt;/code&gt; process, watching files and rebuilding on source code changes. If any changes to &lt;code&gt;build.zig&lt;/code&gt; are detected, or any files observed during execution of that logic, it means &lt;code&gt;configurer&lt;/code&gt; needs to be rerun, meaning that &lt;code&gt;maker&lt;/code&gt; process must exit to give &lt;code&gt;zig build&lt;/code&gt; a chance to repeat the package management logic.&lt;/p&gt;
&lt;p&gt;Now, after the changes described in this devlog entry, it looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;zig build        (the zig compiler)
└─ maker         (build system + package manager)
   └─ configurer (the user&amp;#39;s build.zig logic)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Thus, when configuration needs to be rerun, &lt;code&gt;maker&lt;/code&gt; 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.&lt;/p&gt;
&lt;p&gt;This is almost entirely a non-breaking change, but there are some observable differences:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Zig executable binary size: shrinks 4% from 14.1 to 13.5 MiB (no LLVM, ReleaseSmall)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--maker-opt&lt;/code&gt; flag is replaced by &lt;code&gt;ZIG_DEBUG_MAKER&lt;/code&gt; environment variable&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--zig-lib-dir&lt;/code&gt; flag is replaced by &lt;code&gt;ZIG_LIB_DIR&lt;/code&gt; environment variable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The follow-up issues to this changeset are the main blockers until we tag Zig 0.17.0:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/issues/35538&quot;&gt;build server protocol MVP&lt;/a&gt; (needed to unblock ZLS)&lt;/li&gt;
&lt;li&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/issues/35473&quot;&gt;introduce the concept of adding path dependencies of the build script itself&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/ziglang/zig/issues/20602&quot;&gt;make &lt;code&gt;zig build --watch&lt;/code&gt; detect modifications to the build script and rerun itself&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/issues/35500&quot;&gt;different cwd causes build script cache miss&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Big thanks to Techatrix from the ZLS team for reaching out and working with me on the build server protocol! &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/sponsors/zigtools&quot;&gt;They are seeking sponsorship&lt;/a&gt;, by the way.&lt;/p&gt;
&lt;p&gt;June 26, 2026&lt;/p&gt;
&lt;h2&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/2026/#2026-06-26&quot;&gt;SPIR-V Backend Progress&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Author: Ali Cheraghi&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h2&gt;@SpirvType&lt;/h2&gt;
&lt;p&gt;SPIR-V has a handful of types that couldn’t be expressed in Zig’s type system. The new &lt;code&gt;@SpirvType&lt;/code&gt; builtin has been introduced to address the longest-standing blocker for writing shaders. See &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/ziglang/zig/issues/20550&quot;&gt;#20550&lt;/a&gt;, &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/ziglang/zig/pull/23326&quot;&gt;#23326&lt;/a&gt; and &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/pulls/35461&quot;&gt;#35461&lt;/a&gt; to trace the background.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;JavaScript&quot;&gt;&lt;span class=&quot;syntax-source syntax-js&quot;&gt;&lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;Sampler&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; @&lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;SpirvType&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;sampler&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;Image&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; @&lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;SpirvType&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-object-literal syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt; .image = .{
    .usage = .{ .sampled = &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;format&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;unknown&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;dim&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;@&lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-js&quot;&gt;&amp;quot;&lt;/span&gt;2d&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-js&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;depth&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;unknown&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;arrayed&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-language syntax-boolean syntax-false syntax-js&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;multisampled&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-language syntax-boolean syntax-false syntax-js&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;access&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;unknown&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt;
} }&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;SampledImage&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; @&lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;SpirvType&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-object-literal syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt; .sampled_image = &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;Image&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;RuntimeArray&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; @&lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;SpirvType&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-object-literal syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt; .runtime_array = &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;sampled_image&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; @&lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;extern&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-arithmetic syntax-js&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;addrspace&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;constant&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;SampledImage&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-object-literal syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt;
    .name = &lt;span class=&quot;syntax-meta syntax-object-literal syntax-key syntax-js&quot;&gt;&lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-js&quot;&gt;&amp;quot;&lt;/span&gt;sampled_image&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-js&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt;
    .decoration = .{ .descriptor = .{ .&lt;span class=&quot;syntax-meta syntax-function syntax-declaration syntax-js&quot;&gt;&lt;span class=&quot;syntax-storage syntax-type syntax-accessor syntax-js&quot;&gt;set&lt;/span&gt; &lt;/span&gt;= &lt;span class=&quot;syntax-meta syntax-object-literal syntax-key syntax-js&quot;&gt;&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt; .binding = &lt;span class=&quot;syntax-meta syntax-object-literal syntax-key syntax-js&quot;&gt;&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;1&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt; }&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt;
}&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Execution Mode on the Calling Convention&lt;/h2&gt;
&lt;p&gt;Execution mode info (workgroup size, fragment origin, etc.) is now carried by the calling convention instead of being emitted via inline assembly &lt;code&gt;OpExecutionMode&lt;/code&gt;. The old &lt;code&gt;std.gpu.executionMode()&lt;/code&gt; helper is gone, and the SPIR-V assembler now rejects manual &lt;code&gt;OpExecutionMode&lt;/code&gt; instructions. Two new calling conventions, &lt;code&gt;spirv_task&lt;/code&gt; and &lt;code&gt;spirv_mesh&lt;/code&gt;, were also added for mesh shading pipelines.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;JavaScript&quot;&gt;&lt;span class=&quot;syntax-source syntax-js&quot;&gt;&lt;span class=&quot;syntax-meta syntax-export syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-import-export syntax-js&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;vert&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;callconv&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;spirv_vertex&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-js&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-object-literal syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-export syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-import-export syntax-js&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;frag&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;callconv&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-object-literal syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt; .spirv_fragment = .{ .depth_assumption = .&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;greater&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt; }&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-js&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-object-literal syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-export syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-import-export syntax-js&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;comp&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;callconv&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-object-literal syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt; .spirv_kernel = .{ .x = &lt;span class=&quot;syntax-meta syntax-object-literal syntax-key syntax-js&quot;&gt;&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;8&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt; .y = &lt;span class=&quot;syntax-meta syntax-object-literal syntax-key syntax-js&quot;&gt;&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;8&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt; .z = &lt;span class=&quot;syntax-meta syntax-object-literal syntax-key syntax-js&quot;&gt;&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;1&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt; }&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-js&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-object-literal syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-export syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-import-export syntax-js&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;callconv&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-object-literal syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt; .spirv_task = .{ .x = &lt;span class=&quot;syntax-meta syntax-object-literal syntax-key syntax-js&quot;&gt;&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt; .y = &lt;span class=&quot;syntax-meta syntax-object-literal syntax-key syntax-js&quot;&gt;&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt; .z = &lt;span class=&quot;syntax-meta syntax-object-literal syntax-key syntax-js&quot;&gt;&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;1&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt; }&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-js&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-object-literal syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-export syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-import-export syntax-js&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;mesh&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;callconv&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-object-literal syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt; .spirv_mesh = .{ .stage_output = .&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;output_lines&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt; .max_primitives = &lt;span class=&quot;syntax-meta syntax-object-literal syntax-key syntax-js&quot;&gt;&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt; .max_vertices = &lt;span class=&quot;syntax-meta syntax-object-literal syntax-key syntax-js&quot;&gt;&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;2&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt; }&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-js&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-object-literal syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Capabilities and Extensions from CPU Features&lt;/h2&gt;
&lt;p&gt;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 &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/KhronosGroup/SPIRV-Headers&quot;&gt;SPIRV-Headers&lt;/a&gt; (excluding external vendors for now), and the assembler now rejects any attempt to emit &lt;code&gt;OpCapability&lt;/code&gt; or &lt;code&gt;OpExtension&lt;/code&gt; directly.&lt;/p&gt;
&lt;h2&gt;Multi-Threaded Codegen&lt;/h2&gt;
&lt;p&gt;From day one, the SPIR-V backend ran codegen single-threaded inside the linker thread. Each codegen job now produces an &lt;code&gt;Mir&lt;/code&gt; value just like every other self-hosted backend, and gets scheduled on the compiler’s thread pool.&lt;/p&gt;
&lt;p&gt;The same change brought back two ISel passes that had been removed during earlier refactors: &lt;code&gt;dedup_types&lt;/code&gt; (which merges equivalent type instructions) and &lt;code&gt;prune_unused&lt;/code&gt; (which strips dead code from the final module). These had originally been deleted back when codegen was single-threaded.&lt;/p&gt;
&lt;h2&gt;Object File Linking&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;.spv&lt;/code&gt; files are now recognised as object files. You can compile multiple &lt;code&gt;.zig&lt;/code&gt; files (or external &lt;code&gt;.spv&lt;/code&gt; objects) and have the SPIR-V linker stitch them into a single module.&lt;/p&gt;
&lt;p&gt;Tens of bugs have also been fixed along the way with a nearly 10% increase in total passing behavior tests (49% now) on the &lt;code&gt;spirv64-vulkan&lt;/code&gt; target, &lt;code&gt;std.gpu&lt;/code&gt; was renamed to &lt;code&gt;std.spirv&lt;/code&gt; 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 &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/issues&quot;&gt;Codeberg&lt;/a&gt;. Happy hacking!&lt;/p&gt;
&lt;p&gt;June 25, 2026&lt;/p&gt;
&lt;h2&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/2026/#2026-06-25&quot;&gt;New @bitCast Semantics and LLVM Backend Improvements&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Author: Matthew Lugg&lt;/p&gt;
&lt;p&gt;(Quite long devlog coming up, apologies—I got a little carried away with this one!)&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h2&gt;LLVM Backend Integer Lowering&lt;/h2&gt;
&lt;p&gt;Zig has always lowered arbitrary bit-width integer types (e.g. &lt;code&gt;u4&lt;/code&gt;, &lt;code&gt;i13&lt;/code&gt;, &lt;code&gt;u40&lt;/code&gt;) directly to LLVM IR’s bit-int types (&lt;code&gt;i4&lt;/code&gt;, &lt;code&gt;i13&lt;/code&gt;, &lt;code&gt;i40&lt;/code&gt;). However, we’ve known for a long time that this lowering is not optimal, because LLVM’s documented semantics for representing these types in memory are unnecessarily restrictive to the optimizer. Perhaps more importantly, because Clang never emits LLVM IR like this, these code paths in LLVM have never been properly tested, and so are poorly supported in practice—over the past few years, we have observed many instances of &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/ziglang/zig/issues/17768&quot;&gt;trivial optimizations being missed&lt;/a&gt; and even straight-up &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/issues/35560&quot;&gt;miscompilations&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So, the original goal of the PR was to only use these bit-int types when manipulating values in SSA form, and to zero- or sign-extend them to ABI-sized types (&lt;code&gt;i8&lt;/code&gt;, &lt;code&gt;i16&lt;/code&gt;, &lt;code&gt;i32&lt;/code&gt;, etc) when storing them in memory. This should be well-supported, not least because it matches how Clang lowers C’s &lt;code&gt;_BitInt(N)&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;That change was actually fairly straightforward, but I hit one issue which led me down a bit of a rabbit-hole.&lt;/p&gt;
&lt;h2&gt;The Problem with &lt;code&gt;@bitCast&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;@bitCast&lt;/code&gt; is an interesting builtin. In the past, it was defined as being equivalent to the following sequence of operations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Take a pointer to the operand value&lt;/li&gt;
&lt;li&gt;Cast it to a pointer to the destination type&lt;/li&gt;
&lt;li&gt;Load from that pointer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In other words, it was essentially syntax sugar for reinterpreting bytes of memory. However, over time, we diverged from this definition—for instance, it became allowed to use &lt;code&gt;@bitCast&lt;/code&gt; to reinterpret a &lt;code&gt;[3]u8&lt;/code&gt; as a &lt;code&gt;u24&lt;/code&gt;, even though on most targets &lt;code&gt;@sizeOf(u24)&lt;/code&gt; is greater than &lt;code&gt;@sizeOf([3]u8)&lt;/code&gt; so the above definition would invoke Illegal Behavior.&lt;/p&gt;
&lt;p&gt;Up to now, the LLVM backend had implemented these underspecified semantics for the &lt;code&gt;@bitCast&lt;/code&gt; builtin. However, because that definition involved reinterpreting memory, changing how we store integer types in memory ended up impacting the implementation of &lt;code&gt;@bitCast&lt;/code&gt;, and introducing Illegal Behavior which led to crashes in the compiler test suite.&lt;/p&gt;
&lt;p&gt;The easiest solution to this would probably have been to implement logic in the LLVM backend to approximately match the old behavior. I instead opted for a better solution—implement a new definition of &lt;code&gt;@bitCast&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Redefining &lt;code&gt;@bitCast&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;In 2024, Jacob Young wrote up language proposal &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/ziglang/zig/issues/19755&quot;&gt;#19755&lt;/a&gt; which aimed to solve the problems with &lt;code&gt;@bitCast&lt;/code&gt; by precisely specifying a new set of semantics for it. This proposal was accepted shortly after it was submitted, and in fact, the semantics it details are already implemented by the self-hosted x86_64 backend! So to solve the LLVM backend’s problems, I didn’t necessarily need to match the old &lt;code&gt;@bitCast&lt;/code&gt; semantics—instead, this seemed like a good time to finally get the new semantics implemented &lt;em&gt;everywhere&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;As an aside, another advantage to doing this is that we could take advantage of the compiler’s &lt;code&gt;Legalize&lt;/code&gt; pass, which takes difficult-to-lower operations and rewrites them in terms of simpler operations, so that compiler backends only need to support those simple operations. &lt;code&gt;Legalize&lt;/code&gt; already had functionality, used by the self-hosted x86_64 backend, which converted complex &lt;code&gt;@bitCast&lt;/code&gt; operations into simpler ones, and it could be easily adapted to aid the other compiler backends too (mainly the LLVM and C backends)—but only if they implemented the new semantics.&lt;/p&gt;
&lt;p&gt;Regardless, the point is, I set out on a side quest (which ended up being harder than the &lt;em&gt;original&lt;/em&gt; quest) to implement these new semantics throughout the compiler. This includes not only the LLVM and C backends, but also &lt;code&gt;comptime&lt;/code&gt; execution—after all, Zig allows you to do almost any operation at comptime, &lt;code&gt;@bitCast&lt;/code&gt; included! Because the new semantics are meaningfully different from the old (more on this later), I also had to audit a lot of uses of &lt;code&gt;@bitCast&lt;/code&gt; across the standard library, compiler, and supporting libraries (e.g. &lt;code&gt;compiler_rt&lt;/code&gt;). But after a few mostly-painless fixes for CI failures, I was able to finally get &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/pulls/35711&quot;&gt;my PR&lt;/a&gt; green, and landed it in master yesterday (closing a good few issues in the process!).&lt;/p&gt;
&lt;h2&gt;The New &lt;code&gt;@bitCast&lt;/code&gt; Semantics&lt;/h2&gt;
&lt;p&gt;Now that we’ve gotten through all of the background, it’s finally time for me to actually explain new &lt;code&gt;@bitCast&lt;/code&gt; behavior. Instead of being based on reinterpreting bytes in memory like before, the builtin is now defined in terms of the bits which &lt;em&gt;logically&lt;/em&gt; represent a type.&lt;/p&gt;
&lt;p&gt;Every type which supports &lt;code&gt;@bitCast&lt;/code&gt; has a “logical bit layout”—a representation of that type as an ordered sequence of bits. For instance, &lt;code&gt;u5&lt;/code&gt; is composed of 5 logical bits, which we order from least-significant to most-significant. &lt;code&gt;[2]u5&lt;/code&gt; is composed of 10 logical bits—the 5 from the first element, followed by the 5 from the second element. The new definition of &lt;code&gt;@bitCast&lt;/code&gt; is that it reinterprets the logical bits of one type as the logical bits of a different type.&lt;/p&gt;
&lt;p&gt;The simplest example is to take an unsigned integer, say a &lt;code&gt;u8&lt;/code&gt;, and convert it to a signed integer of the same size, in this case &lt;code&gt;i8&lt;/code&gt;. This operation does exactly what you’d expect—the bits are unchanged, and we just reinterpret the most-significant bit as a sign bit. Also unchanged are the semantics of &lt;code&gt;@bitCast&lt;/code&gt; between an integer type and a &lt;code&gt;packed struct&lt;/code&gt;/&lt;code&gt;packed union&lt;/code&gt; type.&lt;/p&gt;
&lt;p&gt;The place where the new semantics differ from the old is when you get aggregate types (arrays and vectors) involved.&lt;/p&gt;
&lt;p&gt;Consider, for instance, bitcasting a &lt;code&gt;[2]u8&lt;/code&gt; to a &lt;code&gt;u16&lt;/code&gt;. Under the old semantics, the result of this operation depends on the target endian: on big-endian targets, the first array element became the 8 &lt;em&gt;most&lt;/em&gt; significant bits, whereas on little-endian targets, the first array element became the 8 &lt;em&gt;least&lt;/em&gt; significant bits. Under the new semantics, because we only care about &lt;em&gt;logical&lt;/em&gt; bit representation (which is endian-agnostic), the operation behaves identically on every target: the first array element becomes the 8 &lt;em&gt;least&lt;/em&gt; significant bits. As a general rule, the new semantics tend to match the behavior of the old semantics on little-endian targets.&lt;/p&gt;
&lt;p&gt;This definition also allows for some weirder operations, such as converting &lt;code&gt;[2]u3&lt;/code&gt; to &lt;code&gt;@Vector(3, u2)&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;JavaScript&quot;&gt;&lt;span class=&quot;syntax-source syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-js&quot;&gt;&amp;quot;&lt;/span&gt;bitcast [2]u3 to @Vector(3, u2)&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-js&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-block syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;arr&lt;/span&gt;: &lt;span class=&quot;syntax-meta syntax-brackets syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-brackets syntax-js&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-brackets syntax-js&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;u3&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;0b001&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;0b011&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;vec&lt;/span&gt;: @&lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;Vector&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;u2&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; @&lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;bitCast&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;arr&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;syntax-comment syntax-line syntax-double-slash syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-js&quot;&gt;//&lt;/span&gt; Concatenate all bits of `arr` starting with the least-significant bit of `arr[0]` to find the
&lt;/span&gt;    &lt;span class=&quot;syntax-comment syntax-line syntax-double-slash syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-js&quot;&gt;//&lt;/span&gt; logical bit sequence, then read off 2-bit chunks from it to get the elements of the resulting
&lt;/span&gt;    &lt;span class=&quot;syntax-comment syntax-line syntax-double-slash syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-js&quot;&gt;//&lt;/span&gt; vector value `vec`.
&lt;/span&gt;    &lt;span class=&quot;syntax-comment syntax-line syntax-double-slash syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-js&quot;&gt;//&lt;/span&gt;
&lt;/span&gt;    &lt;span class=&quot;syntax-comment syntax-line syntax-double-slash syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-js&quot;&gt;//&lt;/span&gt;     arr[0]         arr[1]
&lt;/span&gt;    &lt;span class=&quot;syntax-comment syntax-line syntax-double-slash syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-js&quot;&gt;//&lt;/span&gt;     0b001          0b011
&lt;/span&gt;    &lt;span class=&quot;syntax-comment syntax-line syntax-double-slash syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-js&quot;&gt;//&lt;/span&gt; -------------  -------------
&lt;/span&gt;    &lt;span class=&quot;syntax-comment syntax-line syntax-double-slash syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-js&quot;&gt;//&lt;/span&gt;  1    0    0    1    1    0
&lt;/span&gt;    &lt;span class=&quot;syntax-comment syntax-line syntax-double-slash syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-js&quot;&gt;//&lt;/span&gt; --------  --------  --------
&lt;/span&gt;    &lt;span class=&quot;syntax-comment syntax-line syntax-double-slash syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-js&quot;&gt;//&lt;/span&gt;   0b01      0b10      0b01
&lt;/span&gt;    &lt;span class=&quot;syntax-comment syntax-line syntax-double-slash syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-js&quot;&gt;//&lt;/span&gt;  vec[0]    vec[1]    vec[2]
&lt;/span&gt;
    &lt;span class=&quot;syntax-meta syntax-try syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-trycatch syntax-js&quot;&gt;try&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;vec&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-brackets syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-brackets syntax-js&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-brackets syntax-js&quot;&gt;]&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-comparison syntax-js&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;0b01&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;syntax-meta syntax-try syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-trycatch syntax-js&quot;&gt;try&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;vec&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-brackets syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-brackets syntax-js&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-brackets syntax-js&quot;&gt;]&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-comparison syntax-js&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;0b10&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;syntax-meta syntax-try syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-trycatch syntax-js&quot;&gt;try&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;vec&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-brackets syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-brackets syntax-js&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-brackets syntax-js&quot;&gt;]&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-comparison syntax-js&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-numeric syntax-js&quot;&gt;0b01&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;expect&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; @&lt;span class=&quot;syntax-meta syntax-import syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-import-export syntax-js&quot;&gt;import&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-js&quot;&gt;&amp;quot;&lt;/span&gt;std&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-js&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;testing&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This kind of operation isn’t very useful most of the time, but it’s there if you need it! For instance, perhaps you want to deconstruct an integer into a vector of individual bits to operate on—that can now be done by a &lt;code&gt;@bitCast&lt;/code&gt; to &lt;code&gt;@Vector(n, u1)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;While doing all of this stuff, I also implemented a couple of smaller accepted proposals—I won’t detail them here, but you can take a look at the issues if you’re interested:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Disallow &lt;code&gt;@bitCast&lt;/code&gt; to/from vectors of pointers (&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/ziglang/zig/issues/18936&quot;&gt;#18936&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Allow &lt;code&gt;@bitCast&lt;/code&gt; on enums (part of &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/issues/35602&quot;&gt;#35602&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course, all of these changed semantics will be explained in the 0.17.0 release notes (hopefully a bit more concisely than what I managed here!), and suggested migration steps outlined.&lt;/p&gt;
&lt;h2&gt;LLVM Backend Performance&lt;/h2&gt;
&lt;p&gt;On a final note, I just wanted to mention that the &lt;em&gt;original&lt;/em&gt; motivation for this branch—changing how the LLVM backend lowers non-ABI integer types—was &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/ziglang/zig/issues/17768#issuecomment-4787726124&quot;&gt;demonstrably successful&lt;/a&gt; at restoring missed optimizations. In fact, the Zig compiler itself—despite not making heavy use of arbitrary bit width integers internally!—saw around 5% performance improvements from the better optimization. This means you might have some minor runtime performance gains to look forward to in 0.17.0!&lt;/p&gt;
&lt;p&gt;Thanks for reading, I hope this was interesting to some of you. Happy hacking!&lt;/p&gt;
&lt;p&gt;May 30, 2026&lt;/p&gt;
&lt;h2&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/2026/#2026-05-30&quot;&gt;ELF Linker Improvements&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Author: Matthew Lugg&lt;/p&gt;
&lt;p&gt;I’ve spent the past few weeks working on our new ELF linker which debuted in Zig 0.16.0. At the time of the 0.16.0 release, this linker implementation was in its fairly early stages, and only really supported linking Zig-only code without any external libraries (even libc)—hence why it was (and still is) disabled by default (it can be enabled with &lt;code&gt;-fnew-linker&lt;/code&gt;). However, quite a lot of progress has been made since that initial release!&lt;/p&gt;
&lt;p&gt;Here’s a nice milestone—as of &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/pulls/35533&quot;&gt;my latest PR&lt;/a&gt;, the new ELF linker is capable of building the self-hosted Zig compiler with LLVM and LLD libraries enabled, a task which requires quite a few features under the hood.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;[mlugg@nebula master]$ # Build the Zig compiler using the new linker:
[mlugg@nebula master]$ zig build -Dno-lib -Dnew-linker -Denable-llvm
[mlugg@nebula master]$ # Use that compiler to build something with LLVM and LLD:
[mlugg@nebula master]$ ./zig-out/bin/zig build-exe ~/hello.zig -fllvm -flld
[mlugg@nebula master]$ ./hello
Hello, World!
[mlugg@nebula master]$
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Of course, an ELF linker isn’t necessarily the most exciting thing in the world, which is why the headline feature of this new linker is its support for fast incremental compilation. After the recent enhancements, it is now possible (on x86_64 Linux) to perform incremental rebuilds while linking external libraries, C sources, etc—without any additional performance overhead! Here’s a clip of me trying it out on &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/andrewrk/tetris&quot;&gt;Andrew’s Tetris clone&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;A few silly changes to Andrew’s Tetris clone being built in around 30ms each.&lt;/p&gt;
&lt;p&gt;Oh, and fast incremental rebuilds also work nicely on the Zig compiler itself:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;[mlugg@nebula master]$ zig build -Dno-lib -Denable-llvm -fincremental --watch
Build Summary: 4/4 steps succeeded
install success
└─ install zig success
   └─ compile exe zig Debug native success 36s

Build Summary: 4/4 steps succeeded
install success
└─ install zig success
   └─ compile exe zig Debug native success 244ms

Build Summary: 4/4 steps succeeded
install success
└─ install zig success
   └─ compile exe zig Debug native success 228ms

Build Summary: 4/4 steps succeeded
install success
└─ install zig success
   └─ compile exe zig Debug native success 288ms

Build Summary: 4/4 steps succeeded
install success
└─ install zig success
   └─ compile exe zig Debug native success 283ms
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The biggest missing feature of this linker implementation right now is that it still does not yet support generating DWARF debug information for Zig code—that’s definitely my next priority. But even without that support, it’s amazing just how useful instant rebuilds can be, for example in any situation where you’re doing a lot of print debugging.&lt;/p&gt;
&lt;p&gt;If you’re using the master branch of Zig and you’re on x86_64 Linux, consider trying out incremental compilation with the new ELF linker if it previously wasn’t working with your project! I expect many codebases to already work great with it, unlocking the ability to rebuild your project in milliseconds. Of course, if you come across any bugs, please do &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/issues&quot;&gt;open an issue&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And if you’re currently sticking to tagged releases of Zig, don’t worry—as Andrew mentioned in his last devlog, Zig 0.17.0 is just around the corner, so it won’t be long before you can try this too!&lt;/p&gt;
&lt;p&gt;May 26, 2026&lt;/p&gt;
&lt;h2&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/2026/#2026-05-26&quot;&gt;Build System Reworked&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Author: Andrew Kelley&lt;/p&gt;
&lt;p&gt;Big branch just landed: &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/pulls/35428&quot;&gt;separate the maker process from the configurer process&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This devlog entry is essentially a preview of the upcoming release notes, but serves as an advanced notice to those who want to help test out the new features and provide feedback that will guide the Zig project moving forward.&lt;/p&gt;
&lt;p&gt;Before, &lt;code&gt;build.zig&lt;/code&gt; files plus the build system implementation were all compiled into one bloated process, in Debug mode. After &lt;code&gt;build.zig&lt;/code&gt; logic finished constructing a build graph in memory, the “build runner” code executed it.&lt;/p&gt;
&lt;p&gt;Now, &lt;code&gt;build.zig&lt;/code&gt; files are compiled into a small process (the “configurer”) in debug mode. After this logic finishes constructing a build graph in memory, it is serialized to a binary configuration file. The parent &lt;code&gt;zig build&lt;/code&gt; process is aware of this file and caches it for next time. While waiting for all that, it asynchronously compiles the build graph execution process (the “maker”) in release mode. Once the configuration file is available and the maker process is finished compiling, the maker process is executed, passing it the configuration file. The maker process only needs to be compiled once per &lt;code&gt;zig version&lt;/code&gt; thanks to the global cache. The maker process then executes the build graph, which is contained within the serialized configuration file.&lt;/p&gt;
&lt;p&gt;The primary motivation of this change was to make &lt;code&gt;zig build&lt;/code&gt; faster, in three ways:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Only the user’s &lt;code&gt;build.zig&lt;/code&gt; logic will be compiled with each change, rather than the entire build system along with it. This is starting to become more valuable now that we have introduced &lt;code&gt;--watch&lt;/code&gt;, &lt;code&gt;--fuzz&lt;/code&gt; and &lt;code&gt;--webui&lt;/code&gt;. The build system can grow more features without making &lt;code&gt;zig build&lt;/code&gt; take longer.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now the build system can skip rerunning the &lt;code&gt;build.zig&lt;/code&gt; logic entirely when it knows nothing will change, for example if you add &lt;code&gt;-freference-trace&lt;/code&gt; to your &lt;code&gt;zig build&lt;/code&gt; command line, it now avoids re-running your &lt;code&gt;build.zig&lt;/code&gt; logic redundantly, using the same configuration as last time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now the process that actually executes the build graph is compiled with optimizations enabled.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To demonstrate points 2 and 3, here is the difference between running &lt;code&gt;zig build --help&lt;/code&gt; before and after:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;Benchmark 1 (34 runs): master/zig build -h
  measurement          mean ± σ            min … max           outliers         delta
  wall_time           150ms ± 5.52ms     145ms …  165ms          4 (12%)        0%
  peak_rss           84.8MB ±  275KB    84.2MB … 85.1MB          0 ( 0%)        0%
  cpu_cycles          593M  ± 4.01M      588M  …  608M           2 ( 6%)        0%
  instructions        995M  ± 52.5K      995M  …  995M           0 ( 0%)        0%
  cache_references   25.8M  ±  165K     25.4M  … 26.1M           0 ( 0%)        0%
  cache_misses        651K  ± 20.1K      619K  …  697K           0 ( 0%)        0%
  branch_misses       918K  ± 7.44K      906K  …  935K           0 ( 0%)        0%
Benchmark 2 (348 runs): branch/zig build -h
  measurement          mean ± σ            min … max           outliers         delta
  wall_time          14.3ms ±  744us    13.2ms … 23.3ms          8 ( 2%)        ⚡- 90.4% ±  0.4%
  peak_rss           78.5MB ±  562KB    77.1MB … 81.4MB          7 ( 2%)        ⚡-  7.4% ±  0.2%
  cpu_cycles         24.1M  ±  821K     22.8M  … 27.1M           3 ( 1%)        ⚡- 95.9% ±  0.1%
  instructions       43.7M  ± 23.8K     43.7M  … 43.8M          56 (16%)        ⚡- 95.6% ±  0.0%
  cache_references   1.46M  ± 14.6K     1.40M  … 1.50M          19 ( 5%)        ⚡- 94.3% ±  0.1%
  cache_misses        142K  ± 4.87K      127K  …  157K           2 ( 1%)        ⚡- 78.1% ±  0.4%
  branch_misses       126K  ± 1.37K      120K  …  129K          12 ( 3%)        ⚡- 86.3% ±  0.1%
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It’s dramatic because before, &lt;code&gt;build.zig&lt;/code&gt; logic was being executed with each &lt;code&gt;zig build&lt;/code&gt; command, but now, the build system uses the cached, serialized configuration instead.&lt;/p&gt;
&lt;p&gt;Aside from performance, I expect third-party tooling such as ZLS to benefit from consuming the serialized configuration file rather than maintaining a fork of the build runner.&lt;/p&gt;
&lt;p&gt;This changeset heavily reworks the internal mechanism of the zig build system, however, it is mostly non-breaking from an API perspective, with the exceptions noted in the PR linked above.&lt;/p&gt;
&lt;p&gt;For most people I’m guessing this is the main breaking change they’ll hit:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;if (b.args) |args| {
    run_cmd.addArgs(args);
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;⬇️&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;run_cmd.addPassthruArgs();
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This removes a capability from build scripts since they can no longer observe those arguments. In exchange, it means that when changing those arguments, build scripts no longer must be rebuilt from source.&lt;/p&gt;
&lt;p&gt;If you’re someone who wants to influence the direction of Zig, this is a good time to upgrade your projects to the development version and try out these changes. We’ll be releasing 0.17.0 within a couple weeks from now. However, if you don’t have time, and you find out that 0.17.0 broke your build, don’t worry, there will be plenty of opportunity to get fixes in for the 0.17.1 tag as well.&lt;/p&gt;
&lt;p&gt;April 08, 2026&lt;/p&gt;
&lt;h2&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/2026/#2026-04-08&quot;&gt;Incremental compilation with LLVM&lt;/a&gt;&lt;/h2&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/2026/#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;p&gt;March 10, 2026&lt;/p&gt;
&lt;h2&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/2026/#2026-03-10&quot;&gt;Type resolution redesign, with language changes to taste&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Author: Matthew Lugg&lt;/p&gt;
&lt;p&gt;Today, &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/pulls/31403&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&gt;&lt;span class=&quot;code-snippet&quot;&gt;const Foo = struct {
    bad_field: @compileError(&amp;quot;i am an evil field, muahaha&amp;quot;),
    const something = 123;
};
comptime {
    _ = Foo.something; // `Foo` only used as a namespace
}
&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&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;JavaScript&quot;&gt;&lt;span class=&quot;syntax-source syntax-js&quot;&gt;&lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-block syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;syntax-entity syntax-name syntax-label syntax-js&quot;&gt;inner&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-js&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;Bar&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;Bar&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-block syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;syntax-entity syntax-name syntax-label syntax-js&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-js&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;align&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;@&lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;alignOf&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;Foo&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-block syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; @&lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-language syntax-undefined syntax-js&quot;&gt;undefined&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Shell&quot;&gt;&lt;span class=&quot;syntax-source syntax-shell syntax-bash&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;$&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; zig build-obj repro.zig&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;error:&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; dependency loop with length 2&lt;/span&gt;
    &lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;repro.zig:1:29:&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; note: type &lt;span class=&quot;syntax-string syntax-quoted syntax-single syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell&quot;&gt;&amp;#39;&lt;/span&gt;repro.Foo&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt; depends on type &lt;span class=&quot;syntax-string syntax-quoted syntax-single syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell&quot;&gt;&amp;#39;&lt;/span&gt;repro.Bar&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt; for field declared here&lt;/span&gt;
    &lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;const&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; Foo = struct &lt;span class=&quot;syntax-meta syntax-group syntax-expansion syntax-brace syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-expansion syntax-brace syntax-begin syntax-shell&quot;&gt;{&lt;/span&gt; inner: Bar &lt;span class=&quot;syntax-punctuation syntax-section syntax-expansion syntax-brace syntax-end syntax-shell&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-logical syntax-continue syntax-shell&quot;&gt;;&lt;/span&gt;
                                &lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;^&lt;span class=&quot;syntax-meta syntax-group syntax-expansion syntax-tilde&quot;&gt;&lt;span class=&quot;syntax-variable syntax-language syntax-tilde syntax-shell&quot;&gt;~&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-expansion syntax-tilde&quot;&gt;&lt;span class=&quot;syntax-variable syntax-language syntax-tilde syntax-shell&quot;&gt;~&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;repro.zig:2:44:&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; note: type &lt;span class=&quot;syntax-string syntax-quoted syntax-single syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell&quot;&gt;&amp;#39;&lt;/span&gt;repro.Bar&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt; depends on type &lt;span class=&quot;syntax-string syntax-quoted syntax-single syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell&quot;&gt;&amp;#39;&lt;/span&gt;repro.Foo&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt; for alignment query here&lt;/span&gt;
    &lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;const&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; Bar = struct &lt;span class=&quot;syntax-meta syntax-group syntax-expansion syntax-brace syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-expansion syntax-brace syntax-begin syntax-shell&quot;&gt;{&lt;/span&gt; x: u32 align(@alignOf(Foo)) &lt;span class=&quot;syntax-punctuation syntax-section syntax-expansion syntax-brace syntax-end syntax-shell&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-logical syntax-continue syntax-shell&quot;&gt;;&lt;/span&gt;
                                               &lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;^&lt;span class=&quot;syntax-meta syntax-group syntax-expansion syntax-tilde&quot;&gt;&lt;span class=&quot;syntax-variable syntax-language syntax-tilde syntax-shell&quot;&gt;~&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-expansion syntax-tilde&quot;&gt;&lt;span class=&quot;syntax-variable syntax-language syntax-tilde syntax-shell&quot;&gt;~&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;note:&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; eliminate any one of these dependencies to break the loop&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/download/0.15.1/release-notes.html#Incremental-Compilation&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/pulls/31403&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;p&gt;February 13, 2026&lt;/p&gt;
&lt;h2&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/2026/#2026-02-13&quot;&gt;io_uring and Grand Central Dispatch std.Io implementations landed&lt;/a&gt;&lt;/h2&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/pulls/31158&quot;&gt;io_uring implementation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/pulls/31198&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/issues/31199&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/issues/31200&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/ziglang/zig/issues/157&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&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;JavaScript&quot;&gt;&lt;span class=&quot;syntax-source syntax-js&quot;&gt;&lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; @&lt;span class=&quot;syntax-meta syntax-import syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-import-export syntax-js&quot;&gt;import&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-js&quot;&gt;&amp;quot;&lt;/span&gt;std&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-js&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;init&lt;/span&gt;: &lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;Init&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;Minimal&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-logical syntax-js&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-js&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-object-literal syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt;
    var &lt;span class=&quot;syntax-meta syntax-object-literal syntax-key syntax-js&quot;&gt;debug_allocator&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-js&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;heap&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-method syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;DebugAllocator&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-object-literal syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;init&lt;/span&gt;;
    const gpa = debug_allocator.&lt;span class=&quot;syntax-meta syntax-function syntax-declaration syntax-js&quot;&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-js&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;;

    var &lt;span class=&quot;syntax-meta syntax-object-literal syntax-key syntax-js&quot;&gt;threaded&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-js&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;Io&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;Threaded&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-method syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;gpa&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-comma syntax-js&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-object-literal syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt;
        .argv&lt;span class=&quot;syntax-meta syntax-object-literal syntax-key syntax-js&quot;&gt;0 = .init(init.args),
        .environ = init.environ,
    });
    defer threaded.deinit();
    const io = threaded.io();

    return app(io);
}

fn app(io: std.Io) !void {
    try std.Io.File.stdout().writeStreamingAll(io, &amp;quot;Hello, World!\n&amp;quot;);
}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Shell&quot;&gt;&lt;span class=&quot;syntax-source syntax-shell syntax-bash&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;$&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; strace ./hello_threaded&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;execve&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;(&lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell&quot;&gt;&amp;quot;&lt;/span&gt;./hello_threaded&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell&quot;&gt;&amp;quot;&lt;/span&gt;./hello_threaded&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell&quot;&gt;]&lt;/span&gt;, 0x7ffc1da88b20 /&lt;span class=&quot;syntax-keyword syntax-operator syntax-regexp syntax-quantifier syntax-shell&quot;&gt;*&lt;/span&gt; 98 vars &lt;span class=&quot;syntax-keyword syntax-operator syntax-regexp syntax-quantifier syntax-shell&quot;&gt;*&lt;/span&gt;/&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-post-cmd syntax-shell&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-shell&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;mmap&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;(NULL, 262207, PROT_READ&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-logical syntax-pipe syntax-shell&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;PROT_WRITE,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; MAP_PRIVATE&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-logical syntax-pipe syntax-shell&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;MAP_ANONYMOUS,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;1&lt;/span&gt;, 0&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-post-cmd syntax-shell&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-shell&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;0x7f583f338000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;arch_prctl&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;(ARCH_SET_FS, 0x7f583f378018&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-post-cmd syntax-shell&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-shell&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;prlimit64&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;(0, RLIMIT_STACK, NULL, &lt;span class=&quot;syntax-meta syntax-group syntax-expansion syntax-brace syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-expansion syntax-brace syntax-begin syntax-shell&quot;&gt;{&lt;/span&gt;rlim_cur=8192&lt;span class=&quot;syntax-keyword syntax-operator syntax-regexp syntax-quantifier syntax-shell&quot;&gt;*&lt;/span&gt;1024&lt;span class=&quot;syntax-punctuation syntax-separator syntax-shell&quot;&gt;,&lt;/span&gt; rlim_max=RLIM64_INFINITY&lt;span class=&quot;syntax-punctuation syntax-section syntax-expansion syntax-brace syntax-end syntax-shell&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-post-cmd syntax-shell&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-shell&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;prlimit64&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;(0, RLIMIT_STACK, &lt;span class=&quot;syntax-meta syntax-group syntax-expansion syntax-brace syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-expansion syntax-brace syntax-begin syntax-shell&quot;&gt;{&lt;/span&gt;rlim_cur=16384&lt;span class=&quot;syntax-keyword syntax-operator syntax-regexp syntax-quantifier syntax-shell&quot;&gt;*&lt;/span&gt;1024&lt;span class=&quot;syntax-punctuation syntax-separator syntax-shell&quot;&gt;,&lt;/span&gt; rlim_max=RLIM64_INFINITY&lt;span class=&quot;syntax-punctuation syntax-section syntax-expansion syntax-brace syntax-end syntax-shell&quot;&gt;}&lt;/span&gt;&lt;/span&gt;, NULL&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-post-cmd syntax-shell&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-shell&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;sigaltstack&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;(&lt;span class=&quot;syntax-meta syntax-group syntax-expansion syntax-brace syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-expansion syntax-brace syntax-begin syntax-shell&quot;&gt;{&lt;/span&gt;ss_sp=0x7f583f338000&lt;span class=&quot;syntax-punctuation syntax-separator syntax-shell&quot;&gt;,&lt;/span&gt; ss_flags=0&lt;span class=&quot;syntax-punctuation syntax-separator syntax-shell&quot;&gt;,&lt;/span&gt; ss_size=262144&lt;span class=&quot;syntax-punctuation syntax-section syntax-expansion syntax-brace syntax-end syntax-shell&quot;&gt;}&lt;/span&gt;&lt;/span&gt;, NULL&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-post-cmd syntax-shell&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-shell&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;sched_getaffinity&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;(0, 128, &lt;span class=&quot;syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell&quot;&gt;[&lt;/span&gt;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&lt;span class=&quot;syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-post-cmd syntax-shell&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-shell&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;8&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;rt_sigaction&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;(SIGIO, &lt;span class=&quot;syntax-meta syntax-group syntax-expansion syntax-brace syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-expansion syntax-brace syntax-begin syntax-shell&quot;&gt;{&lt;/span&gt;sa_handler=0x1019d90&lt;span class=&quot;syntax-punctuation syntax-separator syntax-shell&quot;&gt;,&lt;/span&gt; sa_mask=&lt;span class=&quot;syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell&quot;&gt;[&lt;/span&gt;], sa_flags=SA_RESTORER, sa_restorer=0x10328c0}, &lt;span class=&quot;syntax-meta syntax-group syntax-expansion syntax-brace syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-expansion syntax-brace syntax-begin syntax-shell&quot;&gt;{&lt;/span&gt;sa_handler=SIG_DFL&lt;span class=&quot;syntax-punctuation syntax-separator syntax-shell&quot;&gt;,&lt;/span&gt; sa_mask=&lt;span class=&quot;syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell&quot;&gt;[&lt;/span&gt;], sa_flags=0}, 8) = 0
rt_sigaction(SIGPIPE, &lt;span class=&quot;syntax-meta syntax-group syntax-expansion syntax-brace syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-expansion syntax-brace syntax-begin syntax-shell&quot;&gt;{&lt;/span&gt;sa_handler=0x1019d90&lt;span class=&quot;syntax-punctuation syntax-separator syntax-shell&quot;&gt;,&lt;/span&gt; sa_mask=&lt;span class=&quot;syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell&quot;&gt;[&lt;/span&gt;], sa_flags=SA_RESTORER, sa_restorer=0x10328c0}, &lt;span class=&quot;syntax-meta syntax-group syntax-expansion syntax-brace syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-expansion syntax-brace syntax-begin syntax-shell&quot;&gt;{&lt;/span&gt;sa_handler=SIG_DFL&lt;span class=&quot;syntax-punctuation syntax-separator syntax-shell&quot;&gt;,&lt;/span&gt; sa_mask=&lt;span class=&quot;syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell&quot;&gt;[&lt;/span&gt;], sa_flags=0}, 8) = 0
writev(1, &lt;span class=&quot;syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-expansion syntax-brace syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-expansion syntax-brace syntax-begin syntax-shell&quot;&gt;{&lt;/span&gt;iov_base=&lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell&quot;&gt;&amp;quot;&lt;/span&gt;Hello, World!\n&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-shell&quot;&gt;,&lt;/span&gt; iov_len=14&lt;span class=&quot;syntax-punctuation syntax-section syntax-expansion syntax-brace syntax-end syntax-shell&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell&quot;&gt;]&lt;/span&gt;, 1Hello, World!
) = 14
rt_sigaction(SIGIO, &lt;span class=&quot;syntax-meta syntax-group syntax-expansion syntax-brace syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-expansion syntax-brace syntax-begin syntax-shell&quot;&gt;{&lt;/span&gt;sa_handler=SIG_DFL&lt;span class=&quot;syntax-punctuation syntax-separator syntax-shell&quot;&gt;,&lt;/span&gt; sa_mask=&lt;span class=&quot;syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell&quot;&gt;[&lt;/span&gt;], sa_flags=SA_RESTORER, sa_restorer=0x10328c0}, NULL, 8) = 0
rt_sigaction(SIGPIPE, &lt;span class=&quot;syntax-meta syntax-group syntax-expansion syntax-brace syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-expansion syntax-brace syntax-begin syntax-shell&quot;&gt;{&lt;/span&gt;sa_handler=SIG_DFL&lt;span class=&quot;syntax-punctuation syntax-separator syntax-shell&quot;&gt;,&lt;/span&gt; sa_mask=&lt;span class=&quot;syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell&quot;&gt;[&lt;/span&gt;], sa_flags=SA_RESTORER, sa_restorer=0x10328c0}, NULL, 8) = 0
exit_group(0)                           = &lt;span class=&quot;syntax-keyword syntax-operator syntax-regexp syntax-quantifier syntax-shell&quot;&gt;?&lt;/span&gt;
+++ exited with 0 +++
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Swapping out only the I/O implementation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;JavaScript&quot;&gt;&lt;span class=&quot;syntax-source syntax-js&quot;&gt;&lt;span class=&quot;syntax-storage syntax-type syntax-js&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; @&lt;span class=&quot;syntax-meta syntax-import syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-import-export syntax-js&quot;&gt;import&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-js&quot;&gt;&amp;quot;&lt;/span&gt;std&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-js&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-statement syntax-js&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;init&lt;/span&gt;: &lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;Init&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;Minimal&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-logical syntax-js&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-js&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-object-literal syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt;
    var &lt;span class=&quot;syntax-meta syntax-object-literal syntax-key syntax-js&quot;&gt;debug_allocator&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-js&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;heap&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-method syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;DebugAllocator&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-object-literal syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;init&lt;/span&gt;;
    const gpa = debug_allocator.&lt;span class=&quot;syntax-meta syntax-function syntax-declaration syntax-js&quot;&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-js&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;;

    var &lt;span class=&quot;syntax-meta syntax-object-literal syntax-key syntax-js&quot;&gt;evented&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-key-value syntax-js&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;Io&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;Evented&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-language syntax-undefined syntax-js&quot;&gt;undefined&lt;/span&gt;;
    try evented.&lt;span class=&quot;syntax-meta syntax-function syntax-declaration syntax-js&quot;&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-js&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-parameter syntax-function syntax-js&quot;&gt;gpa&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-parameter syntax-function syntax-js&quot;&gt;,&lt;/span&gt; .&lt;span class=&quot;syntax-meta syntax-block syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-begin syntax-js&quot;&gt;{&lt;/span&gt;
        .&lt;span class=&quot;syntax-variable syntax-parameter syntax-function syntax-js&quot;&gt;argv0&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-parameter syntax-optional syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-method syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;args&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-parameter syntax-function syntax-js&quot;&gt;,&lt;/span&gt;
        .&lt;span class=&quot;syntax-variable syntax-parameter syntax-function syntax-js&quot;&gt;environ&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-parameter syntax-optional syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;environ&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-parameter syntax-function syntax-js&quot;&gt;,&lt;/span&gt;
        .&lt;span class=&quot;syntax-variable syntax-parameter syntax-function syntax-js&quot;&gt;backing_allocator_needs_mutex&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-parameter syntax-optional syntax-js&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-js&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-language syntax-boolean syntax-false syntax-js&quot;&gt;false&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-parameter syntax-function syntax-js&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-end syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;;
    defer evented.&lt;span class=&quot;syntax-meta syntax-function syntax-declaration syntax-js&quot;&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-js&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;;
    const io = evented.&lt;span class=&quot;syntax-meta syntax-function syntax-declaration syntax-js&quot;&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-js&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;;

    return &lt;span class=&quot;syntax-meta syntax-function syntax-declaration syntax-js&quot;&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-js&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-parameter syntax-function syntax-js&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;;
&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function-call syntax-js&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-js&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-other syntax-readwrite syntax-js&quot;&gt;io&lt;/span&gt;: &lt;span class=&quot;syntax-variable syntax-other syntax-object syntax-js&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-js&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-property syntax-object syntax-js&quot;&gt;Io&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-logical syntax-js&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-js&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-object-literal syntax-js&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;{&lt;/span&gt;
    try std.Io.File.&lt;span class=&quot;syntax-meta syntax-function syntax-declaration syntax-js&quot;&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-js&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;syntax-meta syntax-function syntax-declaration syntax-js&quot;&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-js&quot;&gt;writeStreamingAll&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-js&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-parameter syntax-function syntax-js&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-parameter syntax-function syntax-js&quot;&gt;,&lt;/span&gt; &amp;quot;&lt;span class=&quot;syntax-variable syntax-parameter syntax-function syntax-js&quot;&gt;Hello&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-parameter syntax-function syntax-js&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-parameter syntax-function syntax-js&quot;&gt;World&lt;/span&gt;!\&lt;span class=&quot;syntax-variable syntax-parameter syntax-function syntax-js&quot;&gt;n&lt;/span&gt;&amp;quot;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-js&quot;&gt;)&lt;/span&gt;&lt;/span&gt;;
&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-js&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&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;/span&gt;&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;p&gt;February 06, 2026&lt;/p&gt;
&lt;h2&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/2026/#2026-02-06&quot;&gt;Two Package Management Workflow Enhancements&lt;/a&gt;&lt;/h2&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/awebo-chat/awebo&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;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Shell&quot;&gt;&lt;span class=&quot;syntax-source syntax-shell syntax-bash&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;$&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; du&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;sh&lt;/span&gt; zig-pkg/&lt;span class=&quot;syntax-keyword syntax-operator syntax-regexp syntax-quantifier syntax-shell&quot;&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;13M&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;    freetype-2.14.1-alzUkTyBqgBwke4Jsot997WYSpl207Ij9oO-2QOvGrOi&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;20K&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;    opus-0.0.2-vuF-cMAkAADVsm707MYCtPmqmRs0gzg84Sz0qGbb5E3w&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;4.3M&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;   pulseaudio-16.1.1-9-mk_62MZkNwBaFwiZ7ZVrYRIf_3dTqqJR5PbMRCJzSuLw&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;5.2M&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;   uucode-0.1.0-ZZjBPvtWUACf5dqD_f9I37VGFsN24436CuceC5pTJ25n&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;728K&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;   vaxis-0.5.1-BWNV_AxECQCj3p4Hcv4U3Yo1WMUJ7Z2FUj0UkpuJGxQQ&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&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;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Shell&quot;&gt;&lt;span class=&quot;syntax-source syntax-shell syntax-bash&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;$&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; du&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;sh&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-group syntax-expansion syntax-tilde&quot;&gt;&lt;span class=&quot;syntax-variable syntax-language syntax-tilde syntax-shell&quot;&gt;~&lt;/span&gt;&lt;/span&gt;/.cache/zig/p/&lt;span class=&quot;syntax-keyword syntax-operator syntax-regexp syntax-quantifier syntax-shell&quot;&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;2.4M&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;    freetype-2.14.1-alzUkTyBqgBwke4Jsot997WYSpl207Ij9oO-2QOvGrOi.tar.gz&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;4.0K&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;    opus-0.0.2-vuF-cMAkAADVsm707MYCtPmqmRs0gzg84Sz0qGbb5E3w.tar.gz&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;636K&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;    pulseaudio-16.1.1-9-mk_62MZkNwBaFwiZ7ZVrYRIf_3dTqqJR5PbMRCJzSuLw.tar.gz&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;880K&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;    uucode-0.1.0-ZZjBPvtWUACf5dqD_f9I37VGFsN24436CuceC5pTJ25n.tar.gz&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;120K&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;    vaxis-0.5.1-BWNV_BFECQBbXeTeFd48uTJRjD5a-KD6kPuKanzzVB01.tar.gz&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/awebo-chat/awebo/issues/61&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/ziglang/zig/issues/23236&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;&lt;span class=&quot;code-snippet&quot;&gt;zig build --fork=[path]
&lt;/span&gt;&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;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Shell&quot;&gt;&lt;span class=&quot;syntax-source syntax-shell syntax-bash&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;$&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; zig build&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; --&lt;/span&gt;fork&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-option syntax-shell&quot;&gt;=&lt;/span&gt;/home/andy/dev/mime&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;error:&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; fork /home/andy/dev/mime matched no mime packages&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;$&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&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;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Shell&quot;&gt;&lt;span class=&quot;syntax-source syntax-shell syntax-bash&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;$&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; zig build&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; --&lt;/span&gt;fork&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-option syntax-shell&quot;&gt;=&lt;/span&gt;/home/andy/dev/dvui&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;info:&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; fork /home/andy/dev/dvui matched 1 (dvui&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-post-cmd syntax-shell&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;packages&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&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;p&gt;February 03, 2026&lt;/p&gt;
&lt;h2&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/2026/#2026-02-03&quot;&gt;Bypassing Kernel32.dll for Fun and Nonprofit&lt;/a&gt;&lt;/h2&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.youtube.com/watch?v=5IUj1EZwpJY&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/issues/31131&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://github.com/rust-random/rand/issues/111&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://learn.microsoft.com/en-us/windows/win32/seccng/processprng&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&gt;&lt;span class=&quot;code-snippet&quot;&gt;pub extern &amp;quot;kernel32&amp;quot; fn ReadFile(
    hFile: HANDLE,
    lpBuffer: LPVOID,
    nNumberOfBytesToRead: DWORD,
    lpNumberOfBytesRead: ?*DWORD,
    lpOverlapped: ?*OVERLAPPED,
) callconv(.winapi) BOOL;
&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&gt;&lt;span class=&quot;code-snippet&quot;&gt;pub extern &amp;quot;ntdll&amp;quot; fn NtReadFile(
    FileHandle: HANDLE,
    Event: ?HANDLE,
    ApcRoutine: ?*const IO_APC_ROUTINE,
    ApcContext: ?*anyopaque,
    IoStatusBlock: *IO_STATUS_BLOCK,
    Buffer: *anyopaque,
    Length: ULONG,
    ByteOffset: ?*const LARGE_INTEGER,
    Key: ?*const ULONG,
) callconv(.winapi) NTSTATUS;
&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/issues/31131&quot;&gt;Windows: Prefer the Native API over Win32&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;January 31, 2026&lt;/p&gt;
&lt;h2&gt;&lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://ziglang.org/devlog/2026/#2026-01-31&quot;&gt;zig libc&lt;/a&gt;&lt;/h2&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/issues/30978&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&gt;&lt;span class=&quot;code-snippet&quot;&gt;fn strnlen(str: [*:0]const c_char, max: usize) callconv(.c) usize {
    return std.mem.findScalar(u8, @ptrCast(str[0..max]), 0) orelse max;
}
&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/pulls/31037&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/issues/30150&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://codeberg.org/ziglang/zig/pulls/30788&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://wiki.musl-libc.org/libc-test.html&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://www.kptv.com/2026/01/31/live-labor-unions-rally-march-portland-ice-facility-protest/&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 target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://en.wikipedia.org/wiki/Killing_of_Alex_Pretti&quot;&gt;Alex Pretti&lt;/a&gt; and &lt;a target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; href=&quot;https://en.wikipedia.org/wiki/Killing_of_Ren%C3%A9e_Good&quot;&gt;Renée Good&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
</feed>
