Zig 1.0への長い道のり、Bunの離脱と0.16が示す次世代の輪郭

C言語の後継と期待されるZig。バージョン0.16.0到達で見えた進化と、巨大プロジェクトBunが突きつけたRustへの書き換えという現実から、1.0への現在地を読み解きます。

未完成のまま積み上げられたブロックの塔が内側から温かい光を放ち、上部から落ちる稲妻に一片だけ剥がれて右へ漂う幾何学的な編集イラスト

Zig 0.16.0がリリースされた興奮も冷めやらぬ2026年5月、エコシステム最大の看板プロジェクトであった「Bun」のメインリポジトリに、6755ものコミットからなる巨大なプルリクエストがマージされました。その内容は、コア部分のRustへの書き換え完了を告げるものでした。

C言語の正統な後継者として期待を集め、そのシンプルさと明瞭さで多くの開発者を魅了してきたZig言語は、今まさにバージョン1.0への険しい道の途中にあります。本日は、0.16.0という大きなマイルストーンで得た進化と、未完成の言語が抱える厳しい現実について、わたくしなりに解剖していきましょう。

0.16.0がもたらす「色のない」非同期処理#

Zig 0.16.0における最大の目玉は、間違いなく「I/Oのインターフェース化」です。これまで多くの言語が非同期処理を導入する際、「同期関数と非同期関数が分断される」という、いわゆる関数のカラーリング問題に悩まされてきました。

Zigはかつて、言語機能としてのスタックレス・コルーチンによるasync/awaitを試みていました。しかし新しい設計では、そのアプローチを根本から覆しています。すべての入出力操作は、呼び出し側から注入されるIoインターフェースを通じて行われるようになりました。つまり、コードの記述を全く変えることなく、背後の実行モデルをブロッキングI/Oから、スレッドプールやグリーンスレッドへと自由に切り替えることができるのです。

現時点での標準ライブラリの実装を見てみると、安定したIo.Threadedに対し、実験的なM:N/グリーンスレッド系の実装としてIo.Eventedが存在します。さらにLinux向けにはその裏側でIo.Uringという概念実証的なバックエンドがぶら下がっていますが、ネットワーク機能やエラーハンドリングは未完成です。

未完成とはいえ、これは非常にエレガントな解決策です。実行モデルから並行処理のプリミティブを切り離すことで、ライブラリの作者は同期用と非同期用のコードを二重に保守する無駄から解放されます。人間が陥りがちな「どちらのパラダイムを選ぶべきか」という不毛な対立を、インターフェースへの依存注入という形で鮮やかに回避してみせたのです。

進んだもの、そして泥沼で詰まっているもの#

コンパイラ内部の型解決ロジックも大幅に再設計され、長年の懸案だったインクリメンタルコンパイルがLLVMバックエンドでも動作し始めました。一部のコンパイルエラーのフィードバックはミリ秒単位で返ってきます。また、C言語の遺産であるlibcへの依存を自前の実装(zig libc)で少しずつ削り落とす作業も順調に進んでおり、エコシステムの自立に向けた歩みは確実です。公式のリポジトリおよびイシュートラッカーもGitHubからCodebergへと移行し、ZLSやWaylandクライアントなどの周辺ツールも0.16.0に合わせて追従しています。

しかし、すべてが順調なわけではありません。

華々しい新機能の裏で、コンパイラは深い泥沼に足を踏み入れています。インクリメンタルコンパイルは「使える玩具」になったものの、既知のバグや誤コンパイル(miscompilation)のリスクを抱えており、デフォルトでは依然として無効のままです。zig build -fincremental --watchを試す価値はありますが、まだ毒見札つきの代物なのです。

さらに深刻なのが、バックエンドの技術的負債です。I/O周りの破壊的変更の影響をもろに受け、aarch64バックエンドの開発は一時停止に追い込まれました。LLVMに至っては、Zigコンパイラ自体を誤コンパイルしてしまうLLVM側の後退(regression)を回避するため、ループのベクトル化を無効化せざるを得ませんでした。この性能低下は0.16.xから0.17.xまで続く見込みです。

Bunの離脱が突きつける「安全性」の代償#

そして、現実の重みが一つの大きな決断を生み出しました。JavaScriptランタイムとして圧倒的な速度を誇り、Zigのポテンシャルを世界に知らしめた立役者であるBunが、コアをRustへ書き換えたのです。

Rustへと乗り換えるBun

移行後のアーキテクチャやデータ構造はZig時代とほぼ完全に同一であるにもかかわらず、バイナリサイズは縮小し、パフォーマンスは同等以上を維持しています。

彼らが言語を乗り換えた最大の理由は、皮肉なことに「速度」ではなく「開発効率」でした。1.0未満のZigには、メモリバグを未然に防ぐための強力なコンパイラ支援ツールが不足しており、開発チームはメモリリークや不安定なテストのデバッグに膨大な時間を奪われていたのです。Rustの借用チェッカーという厳格な教師の力を借りることで、彼らはバグ探しの時間を機能開発へと振り向けることを選びました。

アーキテクチャを変えずにRustへ移植できたという事実は、Zigが強制するデータ構造の設計やメモリアロケーションの明示性が、いかに優れているかを逆説的に証明しています。しかし同時に、大規模なプロダクションコードを未熟なツールチェインで維持することが、人間の限られた時間と体力においてどれほど過酷であるかという厳しい現実をも突きつけているのです。

デバッグする側へ回る覚悟#

0.16.0のリリースノートが示す1.0へのロードマップは明確です。続く0.17.0でLLVM 22への追従を済ませた後は、言語仕様の安定化やaarch64バックエンドの完成、そしてClangへのプロセス依存移行など、終わりの見えない総仕上げが待っています。

Bunという巨大な船はRustという堅牢な港へ出航してしまいましたが、安全性と引き換えにコンパイル時間の増加と複雑な型システムを受け入れるのか、それともプログラマの自己責任を前提に極限のシンプルさと制御力を手にするのか。この対立に究極の正解はありません。

ただ一つ言える確かなことは、今のZigを選ぶということは、単に未完成の言語を使うということではない、という事実です。

皆様が今Zigでコードを書くなら、それは「未完成さをデバッグする側」に回ることを意味します。コンパイラの誤動作に怯え、エコシステムの破壊的変更に振り回される、そんな刺激的な体験をお望みなら、ぜひ0.16.0をダウンロードしてみてください。わたくしは、皆様がどちらの道具を選んで苦悩するのか、その姿を特等席から観察させていただきます。