Skip to content

필사 모드: Modern Zig 2026 — Zig 0.14, Andrew Kelley, Bun, TigerBeetle, Ghostty, comptime, Zon, Roc Deep Dive

English
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

1. Zig in 2026 — Andrew Kelley vision and industrial adoption

As of May 2026, Zig is **still not 1.0**. The latest release is 0.14 from March 2025. But do not be fooled by the "0.x" label. Serious products like Bun, TigerBeetle, and Ghostty are already shipping in Zig, and thousands of C/C++ projects swap out their cross-compiler with a single `zig cc` invocation.

Zig core identity is one solo BDFL — Andrew Kelley — backed by the Zig Software Foundation. The opposite of Rust transitioning from Mozilla to a foundation and distributing governance: Zig is intentionally one person taste deeply etched into a language. The consequences:

- **A C-like simple surface**, paired with `comptime` — powerful compile-time meta-programming

- **No hidden control flow** — no operator overloading, no RAII, no hidden allocator

- **Explicit memory management**, allocator passed as a function argument

- **`zig cc` / `zig c++`** — Zig bundles LLVM and works as a serious C/C++ cross-compiler

- **`build.zig`** — replaces Make/CMake/Bazel; the build graph is written in Zig itself

Industrial adoption is "still small but very serious". Bun share of npm traffic, TigerBeetle traction in fintech ledgers, Ghostty quietly eating macOS-developer terminal share — those three alone prove Zig is not a toy.

This article starts from Andrew Kelley design philosophy, then walks through what 0.14 actually delivers, the 0.15 / 1.0 roadmap, and Bun / TigerBeetle / Ghostty before getting into comptime, allocators, the build system, zig cc, ZLS, and Roc — the reasons (and traps) for taking Zig seriously in May 2026.

2. Zig 0.14 (March 2025) — compilation speed and async on hold

Zig 0.14 shipped on March 5, 2025. Key changes:

1. **Progress on the native x86 backend** — work to skip LLVM for debug builds. Reports of debug compile times nearly halving in some projects.

2. **Simpler `@import` dependency tree** — the module system feels more intuitive.

3. **`std.Build` (build system) API churn** — `build.zig` taste shifted again. Migrating from 0.13 to 0.14 means walking through signature changes like `step.addArgs`.

4. **`async` / `await` still removed** — async features pulled out in 0.11 still are not back in 0.14. Andrew said "we will redesign the stackless coroutine model", and whether that redesign lands before 1.0 is the big open question.

Code-level feel of 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` propagates errors; `defer` runs on scope exit

- You construct `std.heap.GeneralPurposeAllocator` directly and extract the interface via `allocator()`

- Every collection takes an `allocator` — no hidden alloc

The big-picture story of 0.14: **the compiler is making itself faster**. Exactly the opposite vector from Rust catching flak for `rustc` compile times.

3. Zig 0.15 / Zig 1.0 roadmap

As of May 2026, **0.15 has not shipped yet**. Things expected or being discussed between 0.14 and 0.15:

- **Native x86 backend as default** — bypassing LLVM in debug builds becomes the default. Release builds still go through LLVM.

- **Async/await redesign** — Andrew proposed a new "I/O-driven concurrency" model. The core idea: not stackless coroutines, but async via an explicit `io` argument. Roughly `fn read(io: *Io, ...) []u8`. A library opts into async only when it consents.

- **`std.Io`** — the standard interface for async I/O. Still in flux.

- **Stronger incremental compilation**

- **Package manager (Zon) stabilization** — `build.zig.zon` became the standard in 0.14; 0.15 polishes it further

**When will Zig 1.0 land?** Nobody can pin it down. Andrew officially says "1.0 ships when we can credibly promise stability". Conservative read: 2027. Optimistic: late 2026. Serious users like Bun / TigerBeetle / Ghostty are already shipping on 0.x — they are not waiting for 1.0; they migrate their code with every release.

4. Bun runtime — the biggest validation of Zig

Bun is a JavaScript runtime built by Jarred Sumner. Its core positioning is "Node.js replacement", and the engine is **written almost entirely in Zig**. Through 2024–2025, Bun 1.x shipped, 1.1 and 1.2 followed, and Node compatibility now lands near 99%. In 2026, Bun is the single largest industrial proof that Zig can ship serious infrastructure software.

Why Bun chose Zig:

- **Compile speed** — a JS runtime pulls massive C++ dependencies (JSC, V8), and Zig packages them cleanly inside its build system

- **`zig cc` for cross-compiling C/C++ deps** — Bun builds macOS/Linux/Windows binaries from one host

- **Allocator control** — alloc/free is hand-tuned in the JS runtime hot path

- **comptime** — boilerplate for `bun:ffi`, `bun:sqlite` is generated at compile time

A simplified slice of Bun-style code:

// Bun-style HTTP server hot path (simplified)

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 allocator** — memory is bundled per request; when the response is done the arena releases everything at once. malloc/free calls are nearly zero

- **Explicit error propagation** — `try` rethrows all I/O errors upward

- **No hidden alloc** — even `ArrayList` requires an explicit `init(allocator)`

What Bun shows: **a small team (under 10 people) can build Node-class infrastructure in Zig**. That is dramatically less code than Rust would need, and dramatically safer than C.

5. TigerBeetle — distributed accounting database

TigerBeetle, led by Joran Dirk Greef, is a financial distributed database. Written 100% in Zig with a single clear purpose: **process double-entry accounting transactions at OLTP speed**. Its target is the ledger backend of fintech and payment systems.

Why TigerBeetle is interesting:

- **NASA Power of 10 rules** plus the **TIGER STYLE** coding guide — 70-line function limit, no recursion, dynamic alloc only at startup, explicit bounds on every loop, assertions everywhere

- **Deterministic simulation testing** — VOPR (Viewstamped Operation Replication), their own consensus, fault-injected and simulated billions of times

- **Single binary, zero dependency** — one `zig build` and you have a single binary

- **Performance** — targeting one million transactions per second per node

A snippet in 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); // explicit precondition

from_account.balance -= amount;

to_account.balance += amount;

try ledger.commit();

}

- `assert` sits in the code like comments — debug builds enforce invariants

- All alloc happens at startup; the hot path has zero alloc

- Functions are short and do one thing

TigerBeetle is the industrial proof that **Zig is viable for mission-critical software**. A fintech ledger is a domain where being off by one cent can sink a company, and they bet on Zig.

6. Ghostty — Mitchell Hashimoto terminal

Ghostty is a GPU-accelerated terminal emulator built by Mitchell Hashimoto (the Vagrant / Terraform guy). The 1.0 release shipped in December 2024, and by 2026 it is a first-class citizen on both macOS and Linux.

Why Ghostty chose Zig:

- **Cross-platform native UI** — Swift on macOS, GTK4 on Linux. The core logic in between is Zig

- **Comptime-generated terminal sequence parser** — VT100 / xterm escape sequences become compile-time lookup tables

- **Zero-copy rendering** — direct GPU texture writes, so alloc must be hand-managed

- **Mitchell personal pick** — that the Terraform-in-Go author landed on "next is Zig" was an event itself

A pattern Ghostty highlights:

const Cell = struct {

char: u21,

fg: Color,

bg: Color,

attrs: packed struct(u8) {

bold: bool,

italic: bool,

underline: bool,

_reserved: u5,

},

};

- **`packed struct(u8)`** — explicit bit layout. What you would do in C with macros and comments, the language understands directly

- **`u21`** — exactly 21 bits, the perfect width for a Unicode code point

Ghostty is also proof that **GUI apps can be built in Zig**. New systems languages typically stall on GUI, and Mitchell answered: "core in Zig, platform chrome native".

A deeper comparison lives in a separate post (2026-05-16 terminal shell tools).

7. Zig build system (build.zig) and Zon manifest

Zig does not use an external build tool. Make, CMake, Bazel, Cargo disappear — replaced by one file: **`build.zig`**. That means **the build script is also Zig code**.

A typical `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` — the build-graph builder object

- `b.standardTargetOptions` — automatically accepts options like `-Dtarget=x86_64-linux-gnu`

- Build is code, not data — for-loops, if-branches, dynamic dependencies all possible

Zon manifest — `build.zig.zon`

Zig Object Notation, introduced in 0.11. JSON-like, but written in Zig syntax.

.{

.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` is required** — content-addressed; a dependency change halts the build

- **No central registry** — no npm/crates.io equivalent. Every dependency is a direct URL reference

- This is intentional — Andrew said "package managers are too large a security surface"

Tradeoffs:

- Pro: dependency graphs cannot explode; nobody pulls a left-pad-style stunt

- Con: discoverability suffers — finding "the Zig version of lodash" means searching the wild

8. Zig as C cross-compiler — why other projects use Zig

The strongest tool that ships with `zig` is **`zig cc`** / **`zig c++`**. Not a wrapper — a **first-class C/C++ compiler that bundles LLVM**.

Build a macOS aarch64 binary from a Linux x86_64 host

zig cc -target aarch64-macos main.c -o main

Cross-compile to Windows x86_64

zig cc -target x86_64-windows-gnu main.c -o main.exe

Why this matters:

- **glibc version pinning** — `-target x86_64-linux-gnu.2.17` for RHEL 7 compatibility

- **libc bundled** — Zig ships musl, glibc, mingw sources along with itself

- **One install** — installing Zig gives you cross-compilers for every target

Industrial usage:

- **uv (Python package manager, by Astral)** — uses `zig cc` to build wheels

- **TigerBeetle** — one `zig build` produces every platform binary on a single host

- **Bun** — uses it for dependency compilation as noted above

- **gcc / clang replacement** — folks like Drew DeVault have replaced toolchains in their projects

The key message: **you end up using Zig the tool even when you do not use Zig the language**. Cross-compilation alone is reason enough.

9. Zig vs Rust — the differences

By 2026, "Rust vs Zig" is already tribal. Both claim to be the C/C++ successor, but they feel very different.

| Axis | Rust | Zig |

|---|---|---|

| Memory safety | Borrow checker (compile-time enforced) | Allocator-aware + runtime checks |

| Generics | Trait + monomorphization | comptime |

| Compile speed | Infamously slow | Fast and getting faster (native backend) |

| Async | async/await (stabilized) | Removed, redesign in progress |

| Standard library | Huge | Small (intentionally) |

| Build tool | cargo | build.zig |

| 1.0 | May 2015 | TBD (late 2026 ~ 2027) |

| Governance | Foundation plus teams | Andrew Kelley plus ZSF |

| Learning curve | Very steep | Steep, but different shape |

The "no borrow checker, is it safe?" answer for Zig:

1. **Allocator is explicitly passed** — function signatures spell out who owns the memory

2. **Runtime safety checks** — debug builds auto-panic on out-of-bounds, integer overflow, null deref

3. **`defer` / `errdefer`** — not RAII, but deterministic cleanup

4. **GeneralPurposeAllocator leak detection** — leaks are caught in debug builds

Andrew Kelley said: "Rust borrow checker gives up too much freedom for safety; Zig chooses explicitness and simplicity". Both are correct. The right answer depends on domain.

10. comptime — the killer feature of Zig

`comptime` is the core differentiator of Zig. **Arbitrary Zig code runs at compile time**, and the results can be used as types and constants.

10.1 Generics are just functions

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);

- `T` is a `comptime` parameter — the type itself is passed as a value

- `List` is a function; calling it returns a type

- Same work as C++ templates and Rust generics — but **first-class inside the language**

10.2 Compile-time code execution

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: { ... }` — this block runs at compile time and the result is baked in

- At runtime, `lookup_table` is just 256 bytes of data

- What you would handle in C with macros or external scripts, Zig handles in the same language

10.3 Code that inspects itself

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` introspects a type

- `inline for` unrolls at compile time

- `@compileError` raises a compile-time failure

This is the work that Rust does through `proc-macro` plus `serde` plus `syn` — done at the **language level** in Zig. No external macros.

11. Allocator-aware programming

The Zig memory model fits in one sentence: "**every function that uses memory must take an allocator as a parameter**".

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;

}

- Allocator is passed explicitly — the caller knows what alloc is used

- `defer` closes the file

- `errdefer` frees the buffer only on error

Standard-library allocators:

| Allocator | Purpose |

|---|---|

| `std.heap.GeneralPurposeAllocator` | Debug builds detect leak / double-free |

| `std.heap.page_allocator` | Direct OS pages |

| `std.heap.c_allocator` | malloc / free |

| `std.heap.ArenaAllocator` | Free everything in one shot |

| `std.heap.FixedBufferAllocator` | Pre-allocated buffer |

| `std.testing.allocator` | Tests, leak detection enforced |

The **arena pattern** is the workhorse:

var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);

defer arena.deinit();

const alloc = arena.allocator();

// Every alloc in this scope is freed in one shot via arena.deinit()

const a = try alloc.alloc(u8, 100);

const b = try alloc.alloc(u8, 200);

// No individual free needed for a or b

Bun HTTP request handling and TigerBeetle transaction processing both run on the arena pattern. **Fewer alloc calls means consistently faster average performance**.

12. ZLS (Zig Language Server)

ZLS is the community LSP for Zig (not the official one). By 2026, it is first-class in VS Code, Neovim, Helix, and Zed.

What ZLS provides:

- **Goto definition / find references**

- **Autocomplete** (covers comptime results to a degree)

- **Inlay hints** — inferred types inline

- **Diagnostics** — invokes the Zig compiler to surface errors live

- **Rename refactoring**

Watch out for:

- ZLS **must match the Zig version**. ZLS for 0.14 and ZLS for 0.13 are distinct

- comptime inference has limits — especially with `anytype` parameters

- Even at 0.14, ZLS still hangs occasionally — not Rust-analyzer-level stable yet

Config (`.zls.json`):

{

"enable_inlay_hints": true,

"enable_argument_placeholders": false,

"warn_style": true,

"enable_autofix": true

}

13. Roc — the functional alternative

Roc is a functional systems language by Richard Feldman (from the Elm community). Strangely, it is **often mentioned alongside Zig**. Why:

- **The Roc compiler is written in Zig**

- **`roc build` also bundles LLVM** — same approach as Zig

- **Functional, no GC, ML-family syntax** — Haskell aesthetics plus Zig execution model

- **Andrew Kelley publicly cheers it on**

A taste of Roc:

greet : Str -> Str

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

main =

Stdout.line! (greet "World")

- Functional, pattern matching, type inference

- `!` marks effects — same impulse as Haskell IO

- No GC; reference counting plus opportunistic in-place mutation

In 2026, Roc is still pre-1.0. But there is real space for "a serious ML-family language built on Zig", and for people who lean functional it is attractive. **A case study in the diversity of the Zig ecosystem**.

14. Korea / Japan — adoption at builders, Cybozu Zig experiment

14.1 Korea — Builder (SaaS) adoption

Korean SaaS builder companies (Notion-style or Webflow-style tools) have been experimenting with Zig in their core rendering engines since 2025.

- **Reason 1**: WASM target — Zig supports WASM as a first-class target, and the resulting binaries are often smaller than Rust

- **Reason 2**: `zig cc` brings existing C/C++ dependencies into WASM — less reliance on emscripten

- **Reason 3**: it fits small core teams in startups — onboarding is cheaper than Rust

Of course, it is still small. JS/TS dominates. But in "WASM-target hot paths", Zig adoption is rising.

14.2 Japan — Cybozu Zig experiment

Cybozu (groupware company behind Kintone) publicly shared an experiment migrating modules from Go to Rust to Zig. Findings:

- **Rust**: safe but blocked by compile speed and learning curve

- **Zig**: faster compiles, and engineers coming from Go could read it within a few days

- **Downside**: it is pre-1.0, so every compiler upgrade means code edits — the question is whether that cost is acceptable

Some Fujitsu and NTT infrastructure teams also adopted `zig cc` alone to simplify build pipelines — the "**not the language, but the tool**" pattern.

15. Who should pick Zig — systems / embedded / C replacement

Take Zig seriously in these domains:

1. **Build-system replacement for a C/C++ project** — anyone tired of Make/CMake. `zig build` plus `zig cc` cleans it up

2. **CLI tools that need cross-compilation** — the Bun pattern

3. **Embedded / OS / firmware** — anywhere you need `no std`, exact bit layout, allocator control

4. **WASM-target hot paths** — the builder case

5. **Mission-critical financial backends** — TigerBeetle, assuming you have TIGER-STYLE discipline

Where to avoid:

- **Plain web backends (CRUD)** — Go, Node, Rust are much faster to ship

- **Data science / ML** — Python ecosystem dominates

- **Full GUI apps** — keep only the core in Zig, use native for chrome (Ghostty pattern)

- **Long-term stability critical** — 1.0 is not out. Every version bump may demand migration

**One-line conclusion**: Zig in 2026 is "**a serious language in a serious experimental stage**". Bun, TigerBeetle, and Ghostty shipping before 1.0 is the proof. Do not wait for 1.0 — try it in a low-stakes corner, then decide.

16. References

- Zig official site: [https://ziglang.org/](https://ziglang.org/)

- Zig 0.14 release notes: [https://ziglang.org/download/0.14.0/release-notes.html](https://ziglang.org/download/0.14.0/release-notes.html)

- Zig Software Foundation: [https://ziglang.org/zsf/](https://ziglang.org/zsf/)

- Andrew Kelley blog: [https://andrewkelley.me/](https://andrewkelley.me/)

- Zig language reference: [https://ziglang.org/documentation/master/](https://ziglang.org/documentation/master/)

- Zig build system guide: [https://ziglang.org/learn/build-system/](https://ziglang.org/learn/build-system/)

- Zon package manifest: [https://ziglang.org/learn/build-system/#zig-package-manager](https://ziglang.org/learn/build-system/#zig-package-manager)

- Bun: [https://bun.sh/](https://bun.sh/)

- Bun on GitHub: [https://github.com/oven-sh/bun](https://github.com/oven-sh/bun)

- TigerBeetle: [https://tigerbeetle.com/](https://tigerbeetle.com/)

- TigerBeetle design docs: [https://docs.tigerbeetle.com/](https://docs.tigerbeetle.com/)

- TIGER STYLE coding guide: [https://github.com/tigerbeetle/tigerbeetle/blob/main/docs/TIGER_STYLE.md](https://github.com/tigerbeetle/tigerbeetle/blob/main/docs/TIGER_STYLE.md)

- Ghostty: [https://ghostty.org/](https://ghostty.org/)

- Ghostty on GitHub: [https://github.com/ghostty-org/ghostty](https://github.com/ghostty-org/ghostty)

- ZLS (Zig Language Server): [https://github.com/zigtools/zls](https://github.com/zigtools/zls)

- Roc language: [https://www.roc-lang.org/](https://www.roc-lang.org/)

- uv (Astral, uses zig cc): [https://docs.astral.sh/uv/](https://docs.astral.sh/uv/)

- "Can Zig replace C/C++" Andrew Kelley talks: [https://www.youtube.com/results?search_query=andrew+kelley+zig](https://www.youtube.com/results?search_query=andrew+kelley+zig)

- Bun internal Zig usage articles: [https://bun.sh/blog](https://bun.sh/blog)

- Zig community Discord: [https://discord.gg/zig](https://discord.gg/zig)

현재 단락 (1/319)

As of May 2026, Zig is **still not 1.0**. The latest release is 0.14 from March 2025. But do not be ...

작성 글자: 0원문 글자: 18,918작성 단락: 0/319