Skip to content
Published on

モダン Zig 2026 — Zig 0.14 / Andrew Kelley / Bun / TigerBeetle / Ghostty / comptime / Zon / Roc 徹底ガイド

Authors

1. 2026 年の Zig — Andrew Kelley のビジョンと産業適用

2026 年 5 月時点、Zig はまだ 1.0 ではない。最新リリースは 2025 年 3 月の 0.14 だ。だが「0.x」ラベルに騙されてはいけない。Bun・TigerBeetle・Ghostty といった本気のプロダクトが既に Zig で出荷されており、数千の C/C++ プロジェクトが zig cc の一行でクロスコンパイラを差し替えている。

Zig のコアアイデンティティは Andrew Kelley(アンドリュー・ケリー)というソロ BDFL 一人と、その上に乗る Zig Software Foundation だ。Rust が Mozilla から財団へガバナンスを分散させた方向とは正反対で、Zig は意図的に一人の趣味を深く刻んだ言語である。結果として:

  • C に近いシンプルな表層、しかし comptime という強力なコンパイル時メタプログラミング
  • 隠れた制御フローなし — オペレータオーバーロード、RAII、隠れアロケータなし
  • 明示的なメモリ管理、アロケータを関数引数として渡すパターン
  • zig cc / zig c++ — Zig が LLVM をバンドルし、本格的な C/C++ クロスコンパイラとして動く
  • build.zig — Make/CMake/Bazel を置き換えるビルドシステム。ビルドグラフは Zig コードそのもの

産業適用は「まだ小さいが非常に真剣」。Bun が npm 流量に占めるシェア、TigerBeetle がフィンテックバックエンドに食い込む速度、Ghostty が macOS 開発者ターミナルのシェアを静かに削っていく勢い — この三つだけで「Zig はおもちゃではない」という証明には十分だ。

本記事は Andrew Kelley の設計哲学から始まり、0.14 の実体、0.15 / 1.0 ロードマップ、Bun / TigerBeetle / Ghostty を経て、comptime・アロケータ・ビルドシステム・zig cc・ZLS・Roc まで — 2026 年 5 月時点で Zig を真剣に見るべき理由と落とし穴を一度に整理する。


2. Zig 0.14(2025.3) — コンパイル速度と async 再設計待ち

2025 年 3 月 5 日、Zig 0.14 がリリースされた。主な変更:

  1. ネイティブ x86 バックエンドの安定化が進展 — LLVM をスキップしてデバッグビルドを高速化する作業。デバッグビルドのコンパイル時間が約 2 倍速くなるケースが報告された。
  2. @import 依存ツリーの単純化 — モジュールシステムがより直感的に。
  3. std.Build(ビルドシステム)API の刷新build.zig の書き味がまた変わった。0.13 → 0.14 の移行では step.addArgs などの API シグネチャ変更を要チェック。
  4. async / await は依然撤去中 — 0.11 で一時撤去された非同期機能は 0.14 でも未復帰。Andrew は「スタックレスコルーチンモデルを再設計する」と発言しており、その再設計が 1.0 前に入るかが最大の論点。

0.14 の雰囲気をコードで:

const std = @import("std");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    var list = std.ArrayList(u8).init(allocator);
    defer list.deinit();

    try list.appendSlice("Hello, Zig 0.14!\n");
    try std.io.getStdOut().writeAll(list.items);
}
  • try はエラー伝播、defer はスコープ終了時に実行
  • std.heap.GeneralPurposeAllocator を直接生成し、allocator() でインターフェースを取り出す
  • すべてのコレクションが allocator を受け取る — 隠れ alloc なし

0.14 の大局: コンパイラが自分の足でより速くなっている。Rust が rustc のコンパイル速度で叩かれているのと真逆の方向性だ。


3. Zig 0.15 / Zig 1.0 ロードマップ

2026 年 5 月現在、0.15 はまだリリースされていない。0.14 → 0.15 の間に入ると予想/議論されているもの:

  • ネイティブ x86 バックエンドのデフォルト化 — デバッグビルドで LLVM をバイパスするのがデフォルトに。リリースビルドは引き続き LLVM。
  • async/await 再設計 — Andrew が「I/O-driven concurrency」という新モデルを提案。要点は「スタックレスコルーチンではなく、明示的な io 引数による非同期」。例えば fn read(io: *Io, ...) []u8 のような形。ライブラリが同意した時のみ非同期になる。
  • std.Io — 非同期 I/O の標準インターフェース。まだ変動中。
  • インクリメンタルコンパイルの強化
  • パッケージマネージャ(Zon)の安定化 — 0.14 で build.zig.zon が標準になり、0.15 でさらに磨かれる

Zig 1.0 はいつ出るのか? 誰も明言できない。Andrew は公式に「安定性を約束できる時点で 1.0 を出す」とだけ言っている。保守的に見れば 2027 年、楽観的にみても 2026 年下半期。Bun・TigerBeetle・Ghostty のような本気のユーザーは既に 0.x で出荷しており — 1.0 を待つのではなく、リリースごとに自分のコードを一緒に磨いている。


4. Bun ランタイム — Zig で書かれた最大の検証

Bun は Jarred Sumner(ジャレッド・サムナー)が作った JavaScript ランタイムだ。コアポジショニングは「Node.js の置き換え」、内部は ほぼ全部 Zig で書かれている。2024–2025 年にかけて Bun 1.x がリリースされ、1.1 / 1.2 を経て Node 互換性は 99% 近くに到達した。2026 年時点、Bun は「Zig という言語で本格的なインフラを書ける」最大の産業証拠だ。

Bun が Zig を選んだ理由:

  • コンパイル速度 — JS ランタイムは巨大な C++ 依存(JSC、V8)を引き込む必要があり、Zig はそれをビルドシステム内に綺麗にまとめる
  • zig cc で C/C++ 依存をクロスコンパイル — Bun は macOS / Linux / Windows バイナリを一つのマシンから生成
  • アロケータ制御 — JS ランタイムのコアホットパスで alloc / free を手で管理
  • comptimebun:ffibun:sqlite のような module のボイラープレートをコンパイル時に生成

Bun スタイルのコード断片(簡略化):

// Bun の HTTP サーバホットパス(簡略化)
pub fn handleRequest(
    arena: *std.heap.ArenaAllocator,
    socket: *Socket,
    req: *Request,
) !void {
    var response_buffer = std.ArrayList(u8).init(arena.allocator());
    try writeStatusLine(&response_buffer, 200);
    try writeHeaders(&response_buffer, req);
    try socket.writeAll(response_buffer.items);
}
  • アリーナアロケータ — リクエスト単位でメモリを束ね、レスポンス完了時に arena ごと一気に解放。malloc / free 呼び出しがほぼゼロ
  • 明示的なエラー伝播try ですべての I/O エラーを上に投げる
  • 隠れ alloc なしArrayListinit(allocator) で明示

Bun が示したこと: 小チーム(10 人以下)が Zig で Node クラスのインフラを作れる。Rust より圧倒的にコード量が少なく、C より圧倒的に安全だ。


5. TigerBeetle — 分散会計 DB

TigerBeetle は Joran Dirk Greef が率いる金融用分散 DB。100% Zig で書かれ、単一目的が明確だ — double-entry accounting transactions を OLTP 速度で処理する。フィンテック / 決済システムの ledger バックエンドを狙う。

TigerBeetle が面白い理由:

  • NASA Power of 10 ルール + TIGER STYLE コーディングガイド — 関数 70 行制限、再帰禁止、動的 alloc は起動時のみ、すべてのループに明示的境界、assert を多用
  • deterministic simulation testing — VOPR(Viewstamped Operation Replication)という自製合意アルゴリズムを fault injection で数十億回シミュレート
  • シングルバイナリ、ゼロ依存zig build 一回でバイナリ一つが落ちる
  • performance — ノード当たり毎秒 100 万トランザクションを目標

TIGER STYLE の一部をコードで:

fn transfer(ledger: *Ledger, from: AccountId, to: AccountId, amount: u64) !void {
    assert(from != to);
    assert(amount > 0);

    const from_account = try ledger.lookup(from);
    const to_account = try ledger.lookup(to);

    assert(from_account.balance >= amount); // 事前条件を明示

    from_account.balance -= amount;
    to_account.balance += amount;

    try ledger.commit();
}
  • assert がコメントのように敷かれる — デバッグビルドで invariant を強制
  • すべての alloc は起動時に完了、ホットパスには alloc がない
  • 関数は短く、一つのことしかしない

TigerBeetle は「Zig がミッションクリティカルにも使える」産業証拠だ。フィンテック ledger は 1 円でもズレれば会社が潰れるドメインで、そこに Zig を賭けた。


6. Ghostty — Mitchell Hashimoto のターミナル

Ghostty は Mitchell Hashimoto(ミッチェル・ハシモト — Vagrant / Terraform の作者)が作った GPU 加速ターミナルエミュレータだ。2024 年 12 月に 1.0 がリリースされ、2026 年には macOS・Linux 両方で 1 級市民になっている。

Ghostty が Zig を選んだ理由:

  • クロスプラットフォームネイティブ UI — macOS は Swift、Linux は GTK4。その間にあるコアロジックは Zig
  • comptime でターミナルシーケンスパーサを生成 — VT100 / xterm エスケープシーケンスをコンパイル時にルックアップテーブルへ展開
  • ゼロコピーレンダリング — GPU テクスチャに直接書き込むため alloc を手で管理
  • Mitchell 個人の選択 — Terraform を Go で書いた人物が「次は Zig」と言ったのは事件だった

Ghostty が示すパターン:

const Cell = struct {
    char: u21,
    fg: Color,
    bg: Color,
    attrs: packed struct(u8) {
        bold: bool,
        italic: bool,
        underline: bool,
        _reserved: u5,
    },
};
  • packed struct(u8) — ビットレイアウトを明示。C ならマクロ / コメントでやることを言語が理解する
  • u21 — 正確に 21 ビット整数、Unicode コードポイント表現にぴったりの幅

Ghostty は「Zig で GUI アプリを作れる」証拠でもある。新しいシステム言語は通常 GUI で止まるが、Mitchell は「コアは Zig、プラットフォーム chrome はネイティブ」という答えを示した。

詳細比較は別記事(2026-05-16 ターミナルシェルツール)で扱った。


7. Zig ビルドシステム(build.zig)+ Zon マニフェスト

Zig は外部ビルドツールを使わない。Make・CMake・Bazel・Cargo がすべて消え、代わりに build.zig 一つが入る。つまり ビルドスクリプトも Zig コードだ。

典型的な build.zig の形:

const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const exe = b.addExecutable(.{
        .name = "myapp",
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });

    b.installArtifact(exe);

    const run_cmd = b.addRunArtifact(exe);
    const run_step = b.step("run", "Run the app");
    run_step.dependOn(&run_cmd.step);
}
  • b: *std.Build — ビルドグラフビルダオブジェクト
  • b.standardTargetOptions-Dtarget=x86_64-linux-gnu のようなオプションを自動で受け取る
  • ビルドはデータではなくコード — for ループ、if 分岐、動的依存全て可能

Zon マニフェスト — build.zig.zon

0.11 から導入された Zig Object Notation。JSON 風だが Zig 構文。

.{
    .name = "myapp",
    .version = "0.1.0",
    .minimum_zig_version = "0.14.0",
    .dependencies = .{
        .httpz = .{
            .url = "https://github.com/karlseguin/http.zig/archive/abc123.tar.gz",
            .hash = "1220abcdef...",
        },
    },
    .paths = .{ "src", "build.zig", "build.zig.zon" },
}
  • .hash 必須 — content-addressed、依存が変わるとビルドが止まる
  • 中央レジストリなし — npm / crates.io 相当が存在しない。すべての依存が URL 直接参照
  • これは意図された設計 — Andrew は「パッケージマネージャはセキュリティ表面が大きすぎる」と発言

トレードオフ:

  • 長所: 依存グラフが暴走しない、誰かが left-pad 級の事故を起こせない
  • 短所: discoverability が辛い — 「Zig 版 lodash」がどこにあるか自分で探す必要

8. Zig as C cross-compiler — 他のプロジェクトが Zig を使う理由

zig をインストールするとついてくる最強のツールが zig cc / zig c++ だ。単なるラッパーではなく、LLVM をバンドルした本格的な C/C++ コンパイラである。

# Linux x86_64 上で macOS aarch64 バイナリを作る
zig cc -target aarch64-macos main.c -o main

# Windows x86_64 へクロスコンパイル
zig cc -target x86_64-windows-gnu main.c -o main.exe

何が凄いか:

  • glibc バージョン指定可能-target x86_64-linux-gnu.2.17 で RHEL 7 互換ビルド
  • libc バンドル — Zig は musl、glibc、mingw のソースを一緒に持っている
  • 単一インストール — Zig を一つ入れれば、すべてのターゲット向けクロスコンパイラが揃う

産業利用:

  • uv(Python パッケージマネージャ、by Astral) — wheel ビルドに zig cc を使用
  • TigerBeetlezig build が全プラットフォームバイナリを一つのマシンから生成
  • Bun — 上述のように依存コンパイルに使用
  • gcc / clang 置き換え — Drew DeVault などが自プロジェクトでツールチェーンを差し替えた事例

核心メッセージ: Zig 言語を使わなくても Zig ツールは使うようになる。クロスコンパイルというたった一つの機能のために。


9. Zig vs Rust 論争 — 違い

2026 年に「Rust vs Zig」は既に陣営戦だ。両者とも C/C++ の後継を自任する。だが質感が大きく違う。

RustZig
メモリ安全borrow checker(コンパイル時強制)アロケータ志向 + ランタイムチェック
Genericstrait + monomorphizationcomptime
コンパイル速度遅さで悪名速い、自製バックエンドでさらに速く
Asyncasync/await(stabilized)一時撤去、再設計中
標準ライブラリ巨大小さい(意図的)
ビルドツールcargobuild.zig
1.02015 年 5 月未定(2026 下半期 〜 2027)
ガバナンス財団 + チームAndrew Kelley + ZSF
学習コスト非常に急急、だが質感が違う

Zig の「borrow checker がなくて安全なのか?」への答え:

  1. アロケータを明示的に受け取る — 誰がメモリを所有するかが関数シグネチャに書かれている
  2. ランタイム safety checks — デバッグビルドで out-of-bounds、整数オーバーフロー、null deref が自動 panic
  3. defer / errdefer — RAII ではないが決定的なクリーンアップ
  4. GeneralPurposeAllocator の leak detection — デバッグビルドで leak が検出される

Andrew Kelley は「Rust の borrow checker は安全のために自由を捨てすぎる。Zig は明示性と単純性を選ぶ」と発言した。どちらも正しい。ドメイン次第で答えが違う。


10. comptime — Zig のキラー機能

comptime は Zig のコア差別化要素だ。任意の Zig コードをコンパイル時に実行でき、その結果を型や定数として使える。

10.1 Generics は関数だ

fn List(comptime T: type) type {
    return struct {
        items: []T,
        len: usize,

        pub fn append(self: *@This(), item: T) void {
            // ...
        }
    };
}

const IntList = List(i32);
const StrList = List([]const u8);
  • Tcomptime 引数、型そのものを値として受け取る
  • List は関数、呼び出すと型を返す
  • C++ template、Rust generic と同じ仕事をする — しかし 言語内で 1 級市民

10.2 コンパイル時コード実行

const lookup_table = comptime blk: {
    var t: [256]u8 = undefined;
    for (&t, 0..) |*v, i| {
        v.* = @intCast(i * 2 % 256);
    }
    break :blk t;
};
  • comptime blk: { ... } — このブロックがコンパイル時に実行され、結果が埋め込まれる
  • ランタイムでは lookup_table は 256 バイトのデータとして存在
  • C ならマクロ / 外部スクリプトに頼ることを、Zig は同じ言語内で

10.3 自分自身を検査するコード

fn serialize(value: anytype, writer: anytype) !void {
    const T = @TypeOf(value);
    const info = @typeInfo(T);

    switch (info) {
        .Int => try writer.print("{}", .{value}),
        .Bool => try writer.print("{}", .{value}),
        .Struct => |s| {
            inline for (s.fields) |field| {
                try serialize(@field(value, field.name), writer);
            }
        },
        else => @compileError("unsupported type"),
    }
}
  • @typeInfo で型を introspect
  • inline for はコンパイル時 unroll
  • @compileError でコンパイル時失敗メッセージ

これは Rust の proc-macro + serde + syn がやっていることを、言語レベルで やっている。外部マクロなしで。


11. アロケータ志向プログラミング

Zig のメモリモデルは一文で要約される: 「メモリを使うすべての関数は allocator を引数として受け取らなければならない」。

pub fn readFile(allocator: std.mem.Allocator, path: []const u8) ![]u8 {
    const file = try std.fs.cwd().openFile(path, .{});
    defer file.close();

    const stat = try file.stat();
    const buffer = try allocator.alloc(u8, stat.size);
    errdefer allocator.free(buffer);

    _ = try file.readAll(buffer);
    return buffer;
}
  • アロケータを明示的に受け取る — 関数が何の alloc を使うか呼び出し側が分かる
  • defer でファイルクローズ
  • errdefer でエラー時のみ buffer 解放

標準ライブラリが提供する allocator:

Allocator用途
std.heap.GeneralPurposeAllocatorデバッグビルドで leak / double-free 検出
std.heap.page_allocatorOS ページを直接
std.heap.c_allocatormalloc / free
std.heap.ArenaAllocatorリクエスト単位でまとめて解放
std.heap.FixedBufferAllocator事前確保バッファ
std.testing.allocatorテスト、leak 強制検出

Arena パターンが核心:

var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const alloc = arena.allocator();

// このスコープ内のすべての alloc は arena.deinit() 一発で解放される
const a = try alloc.alloc(u8, 100);
const b = try alloc.alloc(u8, 200);
// a、b 個別 free 不要

Bun の HTTP リクエスト処理、TigerBeetle のトランザクション処理がすべて arena パターン上で動く。alloc 回数が減ることで平均性能が安定して速くなる


12. ZLS(Zig Language Server)

ZLS は Zig 公式ではないコミュニティ LSP だ。2026 年時点、VS Code・Neovim・Helix・Zed すべてで 1 級市民。

ZLS が提供するもの:

  • goto definition / find references
  • autocomplete(comptime 結果もある程度)
  • inlay hints — 推論された型をインライン表示
  • diagnostics — Zig コンパイラを呼び出してエラーをリアルタイム表示
  • rename refactoring

注意点:

  • ZLS は Zig バージョンと合わせる必要がある。0.14 用 ZLS、0.13 用 ZLS は別
  • comptime 推論には限界がある — 特に anytype 引数
  • 0.14 時点でも時々止まる — Rust analyzer レベルの安定性はまだ

設定(.zls.json):

{
  "enable_inlay_hints": true,
  "enable_argument_placeholders": false,
  "warn_style": true,
  "enable_autofix": true
}

13. Roc — 関数型の代替

Roc は Richard Feldman(リチャード・フェルドマン — Elm コミュニティ出身)が作った関数型システム言語だ。奇妙にも Zig と一緒に語られることが多い。理由:

  • Roc コンパイラが Zig で書かれている
  • roc build も LLVM をバンドル — Zig と同じアプローチ
  • 関数型 + GC なし + ML 系構文 — Haskell の美観 + Zig の実行モデル
  • Andrew Kelley が公に応援

Roc コードの一例:

greet : Str -> Str
greet = \name -> "Hello, \(name)!"

main =
    Stdout.line! (greet "World")
  • 関数型、パターンマッチング、型推論
  • ! で effect を明示 — Haskell の IO と似た発想
  • GC なし、リファレンスカウント + opportunistic in-place mutation

2026 年時点、Roc はまだ 0.x。だが「Zig 上に作られた本気の ML 系言語」というポジションがあり、関数型を好む人に魅力的だ。Zig エコシステムの多様性を示す事例


14. 韓国 / 日本 — ビルダー導入、Cybozu Zig 実験

14.1 韓国 — ビルダー(Builder)導入

韓国の SaaS ビルダー企業(Notion / Webflow 系ツールを作る会社)が、2025 年からコアレンダリングエンジンに Zig を実験的に導入し始めている。

  • 理由 1: WASM ターゲット — Zig は WASM を 1 級でサポート、結果バイナリが Rust より小さい場合が多い
  • 理由 2: zig cc で既存 C/C++ 依存を WASM に持ち込む — emscripten 依存を減らす
  • 理由 3: コアチーム規模が小さいスタートアップに合う — Rust 学習コストに対して入り口が良い

もちろんまだ小さい。JS / TS スタックが圧倒的。だが「WASM ターゲットのホットパス」では Zig 採用が増えている。

14.2 日本 — Cybozu(サイボウズ)Zig 実験

サイボウズ(Kintone を作るグループウェア会社)は、一部モジュールを Go → Rust → Zig へ移行する実験を公開した。結果:

  • Rust: 安全だがコンパイル速度 + 学習曲線が問題
  • Zig: コンパイルが速く、Go から移ったエンジニアも数日で読める
  • 欠点: 1.0 ではないのでバージョン更新ごとにコード修正が必要 — このコストを受け入れられるかが判断ポイント

富士通・NTT の一部インフラチームも zig cc だけを導入してビルドパイプラインを単純化した事例がある — 「言語は使わないがツールは使う」パターン。


15. 誰が Zig を選ぶべきか — システム / 組み込み / C 置き換え

以下のドメインなら真剣に Zig を検討せよ:

  1. C/C++ プロジェクトのビルドシステム置き換え — Make / CMake に飽きた人。zig build + zig cc で一気に綺麗になる
  2. クロスコンパイルが必要な CLI ツール — Bun が示したパターン
  3. 組み込み / OS 開発 / ファームウェアno std、正確なビットレイアウト、アロケータ制御が必要な場所
  4. WASM ターゲットのホットパス — ビルダーケース
  5. 金融 / ミッションクリティカルバックエンド — TigerBeetle ケース、ただし TIGER STYLE 級のディシプリンが必要

避けるべき場所:

  • Web バックエンド(CRUD) — Go・Node・Rust の方がはるかに速く書ける
  • データサイエンス / ML — Python エコシステムが圧倒的
  • GUI アプリ全体 — コアだけ Zig、chrome は別(Ghostty パターン)
  • 長期安定性が決定的な場所 — 1.0 がまだ出ていない。バージョン移行コスト覚悟が必要

一行結論: 2026 年の Zig は「真剣な実験段階の真剣な言語」。Bun・TigerBeetle・Ghostty が 1.0 前に出荷していること自体が証拠だ。1.0 を待たず、負担の小さい場所で一度試してから判断すればいい。


16. 参考 / References