On May 14, pull request 30412 landed in the Bun JavaScript runtime repository: 1,009,257 lines added, 4,000 removed, 2,188 files touched. The merge ported the entire Zig codebase to Rust over nine days, and the new tree passes 99.8 percent of Bun's existing test suite on Linux x64. The work was driven by Claude Code, the terminal coding agent that Anthropic shipped after acquiring Bun in December 2025. It is the largest production rewrite credited to an AI agent to date, and the methodology behind it is now the reference workflow any team weighing a similar migration will study.

This is the case study. What the agent loop actually did, why nine days was even plausible, where the rewrite cuts corners that human engineers would not, and what creators and engineering leads should take away when an agentic port is proposed for their own codebase.

Background: Why Bun and Why Rust

Bun shipped in 2022 as a Zig-first JavaScript runtime built around JavaScriptCore (the same engine that powers Safari, maintained at WebKit) plus a hand-rolled bundler and package manager. The pitch was speed: a single binary that replaced Node plus npm plus a bundler, written in Zig for manual memory control and direct C interop. By the time The Register covered the merge, Bun had become one of the most-used alternatives to Node in production startups and a regular fixture in benchmark posts.

The case for moving to Rust was always more political than technical. Zig is a small community, the language is still pre-1.0, and the hiring pool is shallower than Rust's by an order of magnitude. Rust also brings borrow checking, a dominant package ecosystem in cargo, and a standard formatter and linter set. For Anthropic, which acquired Bun explicitly to put a flagship JavaScript runtime behind Claude Code, the rewrite also doubled as a demonstration: if the agent could port a million-line Zig codebase to Rust in days, the proof point about agentic coding velocity would be louder than any synthetic benchmark.

Deep Analysis: How the Nine-Day Port Actually Worked

The agent loop Bun creator Jarred Sumner ran was conceptually straightforward. The hard part is that it scales.

Phase One: Parallel Translation

Phase one of the Bun Rust rewrite: parallel agent translation across Zig source files with Claude Code subagents emitting Rust modules
Phase one of the Bun Rust rewrite. Claude Code's subagents fan out across Zig source files, emitting Rust translations that go into a fix-the-compiler queue.

Claude Code was pointed at the Zig source tree and instructed to emit equivalent Rust modules in parallel. The agent did not try to redesign the architecture. The prompt held the file boundaries from Zig, preserved function signatures wherever possible, and reproduced the existing module structure so the new tree could be evaluated against the same test suite. Sumner has been clear that this was deliberately mechanical translation, not idiomatic Rust. A clean-Rust rewrite would have taken months and would have changed the surface area of the runtime in ways that broke downstream users.

Phase Two: Compile Loop

The output of phase one was a tree that emitted more than 16,000 compiler errors. Phase two fed the errors back to the agent in batches, regenerated affected modules, recompiled, and repeated. The reason this loop is even viable on a project this size is that Rust's compiler error messages are unusually specific. Each error names the file, line, and reason; the agent does not need to guess what is wrong, only how to fix it. The same loop run against a C++ codebase or a less diagnostic compiler would degrade fast.

Phase Three: Test Suite Bisection

Phase three of the Bun Rust rewrite: test-suite-driven repair loop, with Claude Code patching modules to push the Linux x64 pass rate from 70 to 99.8 percent
Phase three. Once the new tree compiles, the agent runs the existing Zig test suite and patches modules until the Linux x64 pass rate climbs from roughly 70 percent toward 99.8.

Once the tree compiled, the agent ran Bun's existing test suite, took the first failing test, traced it back to the module that owned the failing behavior, and patched. The pass rate climbed from roughly 70 percent at the end of phase two to 99.8 percent over the next several days. The remaining 0.2 percent is a long tail of platform-specific behavior the agent could not easily reproduce in its sandbox: edge cases around glibc version detection, Linux capability flags, and a handful of process management corners that depend on the host kernel.

Phase Four: Cleanup PR

A companion PR removed roughly 600,000 lines of legacy Zig code. Sumner titled it "ai slop" himself, and GitHub's automated anti-AI-slop detection flagged the PR on submission, which Sumner posted screenshots of. The naming was a joke, but the underlying tension is real: the codebase now ships with substantial machine-generated code under human review.

The 13,000 Unsafe Block Problem

The single most discussed line in the post-merge coverage is the unsafe count. byteiota's analysis found more than 13,000 unsafe blocks in the new tree, roughly 181 times the density of the uv Python tooling project at comparable size. Some of that is structural and unavoidable. Bun's FFI surface against JavaScriptCore requires unsafe because the language boundary is C and there is no way to expose the engine handles otherwise. The rest is the legacy of the agent porting Zig idioms directly: raw pointers, manual lifetime management, and explicit deallocation translated into unsafe Rust instead of being rewritten around the ownership model.

The practical risk is concentrated, not diffuse. Rust's unsafe contract is that the programmer is responsible for upholding invariants the compiler can no longer check. A codebase with 13,000 unsafe blocks has 13,000 places where memory-safety bugs can hide. The first weeks of upstream issue volume after the merge will land disproportionately in those blocks. None of this makes the rewrite a bad idea, but it does mean the new tree should be treated as a release candidate for at least a quarter, not a stable LTS.

Impact on Creators and Engineering Teams

Three concrete shifts follow from the merge.

First, the agent-driven port is now the reference workflow for large migrations. Any team running a large Zig, Go, or C++ codebase will now field the question: could Claude Code, or one of its competitors like Grok Build, do this for us? The answer increasingly is yes for the translation phase and no for the redesign phase. Treat the rewrite as a starting tree for human review, not a finished product.

Second, language transitions get cheaper. The economic case for staying on a niche language because the rewrite cost is prohibitive collapsed at the moment a million-line port shipped in nine days. Niche languages still win on technical merits. They no longer win on switching cost.

Third, the review bottleneck moves upstream. The constraint in agent-driven engineering is no longer typing speed or compiler intuition; it is whether senior engineers can review the volume of code an agent emits. Bun's PR added 1,009,257 lines. No human is reviewing all of it in detail. The discipline shifts to high-leverage review of architectural and unsafe boundaries, plus integration tests that exercise the parts an agent cannot reason about (kernel interfaces, platform quirks, networking edge cases).

Key Takeaways

  • 1,009,257 lines of Rust shipped to Bun on May 14 via PR 30412, replacing the Zig core.
  • The port ran for nine days on Claude Code using a four-phase loop: parallel translation, compile-error fixup, test-suite bisection, and a cleanup PR.
  • The new tree passes 99.8 percent of the existing Zig test suite on Linux x64. The remaining 0.2 percent is platform-specific.
  • 13,000-plus unsafe blocks are the largest open risk in the new tree. Most are at the JavaScriptCore FFI boundary; a meaningful fraction reflect direct translation of Zig idioms rather than Rust-native redesign.
  • The merge proves the agent-driven port pattern at production scale and resets the economics of language transitions.
  • The review bottleneck is now senior engineering time spent on architectural and unsafe boundaries, not typing speed.

What to Watch

Three indicators over the next quarter will determine whether the Bun rewrite is a turning point or a one-off. The first is upstream issue volume against the new release tree: if it stays in line with prior Bun release cycles, the agent loop validated itself. If it spikes, the unsafe blocks and the platform-specific 0.2 percent gap are where the bugs will land. The second is whether other large open-source projects announce comparable ports. A Go-to-Rust port on a project the size of Caddy or a C++-to-Rust port on a project the size of Envoy would confirm the pattern outside Anthropic's home turf. The third is the response from the rest of the agent market. Grok Build's launch on May 15 explicitly leaned on parallel 16-agent dispatch and a 2-million-token context, which is the shape this kind of work rewards. The next major port shipped on Grok Build or Cursor Composer 2.5 will tell us whether Claude Code's nine-day record was a Claude Code property or just an artifact of who happened to attempt it first.

FAQ

Did Claude Code write all million lines unsupervised?

No. The agent generated the bulk of the Rust translation, but every batch ran through compiler error feedback and the existing Zig test suite as ground truth. Sumner reviewed and rewrote significant sections, and the cleanup PR that removed 600,000 lines of Zig was a deliberate human-driven step. The right description is human-supervised agent translation at scale, not autonomous engineering.

Why nine days, not weeks or months?

Three factors compress the timeline. Bun's existing Zig codebase had strong type information that translates cleanly to Rust generics. Rust's compiler emits unusually specific error messages, which feeds the agent loop without ambiguity. And Bun's existing test suite was extensive enough to act as ground truth, so the agent had a tight oracle for whether each translation worked. Take any of those three away and the same loop on a different codebase would run much longer.

Should other teams attempt an agent-driven Rust port right now?

Yes for the translation phase, with caution. The pattern works when three preconditions hold: a strong existing test suite, a compiler that produces specific error messages, and a senior engineer willing to review architectural and unsafe boundaries. Without those, the agent loop produces a tree that compiles and looks reasonable but contains subtle bugs the suite never catches.

Is the 99.8 percent pass rate good enough for production?

Not for risk-averse production workloads yet. The remaining 0.2 percent and the 13,000 unsafe blocks are exactly where production incidents typically surface. Treat the new Rust tree as a release candidate, pin to Bun 1.3.14 for now if you ship Bun in production, and revisit once the post-merge issue tracker stabilizes over the next four to eight weeks.

What does this mean for the Zig community?

Less than the headline suggests. Bun was the most visible Zig consumer in the JavaScript world, and the rewrite is a real signal that switching cost is no longer a moat. But Zig retains its technical advantages for systems where manual memory control matters and the borrow checker gets in the way, and the language community continues to ship. The Bun migration is a signal that high-profile Zig adoption is now contingent on whether the maintainers prefer Zig, not on whether a rewrite is feasible.