AI Newsway

Bun's Zig-to-Rust Port Took 11 Days and 64 Parallel Agents

The largest agent-authored rewrite yet shipped in production β€” and the regressions it let through are the interesting part

|6 min read0
AI Summary
Bun's JavaScript runtime was ported from 535,496 lines of Zig to Rust in 11 days using roughly 50 Claude Code workflows across 64 parallel agent instances, each implementer paired with adversarial reviewers. Bun v1.4.0 fixes 128 bugs from the last Zig release and stops a persistent bundler memory leak, though HTTP throughput rose only 2 to 5 percent. Nineteen semantic regressions still reached the merge, and Zig's creator disputes the reasoning.
Ferris, the Rust programming language mascot, at the Rust assembly during the 38C3 conference β€” Bun's runtime now compiles as Rust rather than Zig.
Ferris, the Rust programming language mascot, at the Rust assembly during the 38C3 conference β€” Bun's runtime now compiles as Rust rather than Zig.

Bun, the JavaScript runtime, bundler and package manager, now runs on Rust rather than Zig, and the port that got it there took 11 days of continuously supervised agent workflows rather than the year its creator budgeted for human engineers. Jarred Sumner documented the process in detail, and with Bun v1.4 now shipping β€” Claude Code and Prisma's Compute beta both run on it β€” there is enough production evidence to ask what a million lines of machine-written systems code actually costs to trust.

Key takeaways

  • Bun's 535,496 lines of Zig across 1,448 files were ported by roughly 50 Claude Code workflows sharded across four git worktrees running 16 agent instances each, peaking at about 1,300 lines per minute and 695 commits in one hour.
  • Every implementer agent was paired with two adversarial reviewers that saw only the diff and were instructed to assume the code was wrong.
  • Bun v1.4.0 fixes 128 bugs that still reproduce in v1.3.14, the last Zig release, while HTTP throughput improved only 2–5 percent.

What made a million-line diff reviewable at all

The precondition was luck that Sumner had banked years earlier: Bun's test suite is written in TypeScript, so it validates behaviour without caring which language implements the runtime underneath. That gave the port a fixed oracle with more than a million assertions, unchanged throughout. A rewrite whose tests lived in the source language would have had no such anchor.

The second decision was structural. Rather than one agent writing and checking its own work, Sumner split the roles: one implementer, two or more adversarial reviewers in separate context windows receiving only the diff, then a separate fixer applying the findings. His stated reasoning is behavioural rather than technical β€” the model that wrote the code wants it merged, exactly as a human author does, so the reviewer has to be a different instance with a different instruction. Published examples include a Box<uv::Pipe> dropped while libuv still held the pointer, an eagerly-evaluated unwrap_or that panicked on valid CSS color-mix(), and a timespec conversion that produced negative nanoseconds for pre-1970 file timestamps. All three compiled cleanly.

Third, when output went wrong the fix was applied to the loop, not the artefact. Agents clobbered each other with git stash within two minutes of the first full run; the response was to rewrite the workflow's instructions rather than repair the damaged commits. Roughly three hours of planning produced a PORTING.md mapping Zig idioms to Rust and a LIFETIMES.tsv recording the intended lifetime of every struct field β€” both themselves adversarially reviewed before a line was ported.

The regressions that compiled clean

What slipped through is more instructive than what was caught. Sumner reports that most regressions came from constructs that look identical in both languages and behave differently. Zig's assert is a function, so its argument evaluates in every build; Rust's debug_assert! is a macro that erases the whole expression in release. A side effect living inside that assertion β€” inserting a file into the hot-reload graph β€” silently stopped running in release builds, breaking React fast refresh while debug builds stayed green.

Others followed the same shape. A helper that had quietly ignored a trailing odd byte was ported to bytemuck::cast_slice, which panics on one instead, crashing the process on a UTF-16 byte order mark. A placeholder constant left at 64 lowered the interned-filename ceiling from 8.4 million to 270,272, a limit real projects hit. Bun's colour-marker formatter lost Zig's compile-time evaluation and began rewriting markers inside substituted arguments. InfoQ counts 19 such semantic regressions, alongside 11 rounds of security review and 15 pull requests from continuous parser fuzzing. None of these were memory-safety failures β€” the borrow checker did its job. They were meaning failures, which is the category no compiler catches.

What the rewrite actually bought

The performance numbers are modest and honestly reported: HTTP throughput up 2 to 5 percent, a vite build moving from 1.69 to 1.65 seconds. The real return was memory discipline. Rust's Drop runs cleanup automatically where Zig's defer had to be written at every call site, and a benchmark bundling the same project 2,000 times in one process β€” which leaked roughly 3 MB per build on v1.3.14, without bound β€” now levels off. Binary size fell by about 20 percent on Linux and Windows once linker optimisations and ICU trimming were combined with the port. Claude Code has run the Rust build since v2.1.181 in June; startup on Linux got 10 percent faster and, as Sumner puts it, barely anyone noticed.

The objection from Zig's creator

Zig author Andrew Kelley published a pointed rebuttal, arguing the framing misdirects: bugs are eliminated by dedicating engineering resources to them, not by choosing between a style guide and a language feature. His sharper question is about consistency β€” if Bun's test suite was not sufficient to catch bugs in the Zig code, it is hard to see why it should be sufficient to validate a million lines of unreviewed generated Rust.

It is a fair challenge, and the honest answer is that the suite was not the only control; adversarial review, Miri in CI, LeakSanitizer and round-the-clock fuzzing were layered on top. Whether that stack substitutes for human comprehension of the code is precisely what remains untested.

Why this one is worth watching

The cost figures Sumner published β€” around $165,000 at API pricing, from 5.9 billion uncached input tokens and 690 million output tokens before merge β€” reprice a decision that used to be effectively permanent. Language choice for a mature codebase was a one-way door; it is now a line item. Anthropic, which acquired Bun in December 2025 and employs Sumner, has an obvious interest in that conclusion, and this is one of several agent-run rewrites shipped this year. The open question is maintenance: a codebase no human has read end-to-end still has to be extended, debugged and reasoned about by people for years. Bun, with 22 million monthly CLI downloads, is where the industry finds out.

FAQ

Did an AI write all of Bun's Rust code unsupervised?

No. Sumner monitored the workflows throughout the 11 days, read outputs manually and repeatedly edited the loop when agents produced bad results. He also reviewed the port by checking that the adversarial reviewers were catching real divergences, and read substantial portions of the Zig and Rust side by side.

Why did the port take 11 days when reports say four months?

The 11 days covers the port itself, from kickoff to the full test suite passing on every platform. The longer figure reflects the elapsed time through additional validation and release: the write-up appeared in July 2026 and the stable Bun v1.4.0 followed in August.

Is Bun still written in Zig at all?

No. Bun v1.3.14 was the last Zig release and v1.4.0 is the first Rust one. About 20 percent of Bun remains C++, including embedded dependencies such as JavaScriptCore and uWebSockets, which the rewrite did not touch.

How do you feel about this article?

SJ

Discussion

Sign in to post
Loading...

Related articles

A Poisoned Rust Crate Was Live for 86 Minutes. It Had 245 Million Downloads.
Developer Tools

A Poisoned Rust Crate Was Live for 86 Minutes. It Had 245 Million Downloads.

Malicious releases of arrayref, internment and append-only-vec pulled an infostealer through a typosquatted proc-macro1 dependency during compilation.

Seung Jung29 days ago
Researchers Reached OpenAI's Internal Repo Through a Forum Image Bug
Developer Tools

Researchers Reached OpenAI's Internal Repo Through a Forum Image Bug

Hacktron AI chained a libheif heap overflow with an OpenAI SSO flaw to reach employee Codex accounts and the openai/openai monorepo. Both bugs are patched.

Seung Jung3 days ago
Perplexity Let Hundreds of Agents Write Its Database. Deploy Rights Stayed Human.
Developer Tools

Perplexity Let Hundreds of Agents Write Its Database. Deploy Rights Stayed Human.

Perplexity replaced DynamoDB with CobbleDB, a 40,000-line Rust store built in two months by two engineers and hundreds of agents barred from deploying it.

Seung Jung4 days ago
832,378 Lines of Rust in 14.5 Weeks: Inside an Agent-Run Rewrite
Developer Tools

832,378 Lines of Rust in 14.5 Weeks: Inside an Agent-Run Rewrite

GitHub converted 430,000 lines of TypeScript into 832,378 lines of Rust in 14.5 weeks using coding agents. Memory use fell from 1,383MB to 126MB.

Seung Jung2 days ago
Claude Code Projects Returns as a Coordinator That Runs Parallel Cloud Threads
Developer Tools

Claude Code Projects Returns as a Coordinator That Runs Parallel Cloud Threads

Anthropic's redesigned Claude Code Projects puts a coordinator above worker threads, each a full cloud session on its own branch, with shared memory.

Seung Jung3 days ago
Zed's Delta Replaces Pull Requests With Agent Threads
Developer Tools

Zed's Delta Replaces Pull Requests With Agent Threads

Zed's Delta swaps the pull request for a shared thread where agents and reviewers work from the same context. Its own repo already has PRs off.

Seung Jung7 hours ago