[KongchangAI]
· 3 min read· 1,919 words

Bun Rewrote a Million Lines of Code in 11 Days with Claude Code: A New Paradigm for AI-Assisted Programming

Bun Rewrote a Million Lines of Code in 11 Days with Claude Code: A New Paradigm for AI-Assisted Programming

Bun rewrote 1M+ lines of Zig into Rust in 11 days using Claude Code for $165K.

Bun author Jared Sumner used Claude Code's dynamic workflows to rewrite over one million lines of Zig code into Rust in just 11 days, spending $165,000 — a task that would have taken 3 engineers a full year and cost $600K. The migration used ~50 agentic workflows, adversarial multi-model code review, and Linux cgroups to manage AI agent coordination, resulting in 19 regressions, 128 bug fixes, 20% smaller binaries, and significantly lower memory usage.

An Experiment That Defies Expectations

Jared Sumner, the author of the JavaScript runtime Bun, recently published a technical blog post detailing how he rewrote over one million lines of Zig code into Rust in 11 days. The key tool behind this feat was Anthropic's Claude Code and its newly introduced dynamic workflows. Tech blogger Theo offered an in-depth analysis, suggesting this post may become a landmark document cited repeatedly in the coming years — it clearly demonstrates how AI-assisted programming can accomplish engineering tasks that were once considered nearly impossible.

Bun was born in April 2021, when Jared spent a year building this ambitious project from scratch in Zig, working out of a small apartment in Oakland, San Francisco. Today, Bun's CLI is downloaded over 22 million times per month, with first-class support from platforms like Claude Code, Vercel, Railway, and DigitalOcean. However, the sheer size of the codebase has continuously introduced stability challenges.

that context window

Why Migrate from Zig to Rust

Zig's Trade-offs and Bun's Pain Points

Jared maintains deep respect for Zig throughout his blog, explicitly stating: "Without Zig, Bun wouldn't have been possible at all."

Zig is a systems programming language developed by Andrew Kelly starting in 2015, positioned as a modern alternative to C. Its core design philosophy is "no hidden control flow, no hidden memory allocations" — unlike C++'s RAII (Resource Acquisition Is Initialization) or Rust's ownership system, Zig deliberately avoids constructors, destructors, and exception mechanisms, requiring programmers to explicitly handle resource cleanup at every call site (typically via the defer keyword). This design makes code behavior extremely transparent, which works well in embedded systems and low-level OS development, but it means memory safety depends entirely on programmer discipline rather than compiler enforcement.

Bun, however, has a unique requirement: it must blend a garbage-collected (GC) JS engine with manual memory management. This is an exceptionally rare need that almost no language is specifically designed for. Without constructors and destructors, cleanup logic must be written explicitly with defer at every call site. Correctly managing the lifetimes of GC values alongside manually managed values has been the primary source of Bun's stability issues: memory leaks, double-frees, and forgetting to free memory on error paths occurred frequently.

Compiler Errors Beat Style Guides

Jared tried many approaches to suppress these bugs: patching the Zig compiler to add AddressSanitizer, running ASAN checks on every commit, running Fuzzilli 24/7, and building end-to-end memory leak tests.

AddressSanitizer (ASAN) is a memory error detection tool developed by Google. It uses compiler instrumentation to track the allocation and deallocation state of every memory block at runtime, detecting heap overflows, stack overflows, use-after-free, and double-free issues — typically at around 2x performance overhead. Fuzzilli is a coverage-guided fuzzing framework specifically designed for JavaScript engines, developed and open-sourced by Apple. It automatically generates large numbers of syntactically valid JS code variants to trigger engine edge cases. Jared integrated both of these industrial-grade testing tools into Bun's Zig codebase and ran them continuously 24/7 — already a top-tier quality assurance investment. But this only reinforced the point: runtime detection is inherently less reliable than static compiler guarantees, because ASAN can only catch issues in code paths already covered by test cases.

But he came to realize that relying on style guides to govern memory management — enforced essentially through code review — has limited reliability. Rust's borrow checker, on the other hand, turns use-after-free and double-free errors into compile-time errors.

Rust's Borrow Checker is the core static analysis component of its compiler. Through three rules — Ownership, Borrowing, and Lifetimes — it eliminates memory safety vulnerabilities at compile time. Specifically: each value has exactly one owner; there can be multiple immutable references or exactly one mutable reference, but not both simultaneously; and references cannot outlive the data they point to. This ruleset can theoretically eliminate the two most common memory vulnerabilities in C/C++ — use-after-free and double-free — without the performance overhead of a runtime garbage collector. The trade-off is a steep learning curve, as programmers must rebuild their mental model of memory management. As Theo emphasized: "Compiler errors are a better feedback loop than style guides, especially when code is written by AI agents — getting feedback from the compiler as early as possible is invaluable."

fathomable

How AI Handled a Mechanical Million-Line Migration

Full Rewrite Instead of Incremental Migration

Drawing on his previous experience porting ESBuild from Go to Zig, Jared chose a "full rewrite all at once" strategy rather than an incremental approach. Incremental rewrites introduce a large amount of temporary glue code that often never gets removed. His strategy: first do a faithful, mechanical translation from Zig to Rust, then gradually refactor into idiomatic Rust after the 1.4 release.

50 Dynamic Workflows in a Loop

Claude Code is Anthropic's command-line AI programming tool for developers. Its Dynamic Workflows feature allows users to break complex engineering tasks into automated loops that can be executed iteratively. Unlike traditional single-turn AI assistance, dynamic workflows support multi-step task orchestration: the AI can execute shell commands, read and write files, run tests, parse error output, and adjust its next actions accordingly — forming a "perceive-decide-act" autonomous loop. This is essentially the core capability of Agentic AI: rather than passively answering questions, the AI actively drives the engineering process forward until a preset goal is reached (e.g., "all tests passing").

The entire migration used approximately 50 dynamic workflows, running continuously in Claude Code for 11 days. Each workflow was a loop: execute a task, wait for feedback, review results, apply changes, and repeat. Specific workflows included:

  • Generating a Zig-to-Rust porting guide (porting.md)
  • Porting each of the 1,448 .zig files to .rs files one by one
  • Fixing compilation errors in each crate
  • Getting individual subcommands and the full test suite to pass
  • Multiple rounds of refactoring and cleanup

A key mechanism was adversarial code review: each implementer was paired with two or more adversarial reviewers whose sole job was to find bugs and prove the code didn't work. Implementers didn't review, and reviewers didn't implement. Theo also added that having different reviewers use models from different vendors (e.g., one using Codex, one using Claude) significantly improved review quality.

The Engineering Challenge of Agents Stomping on Each Other

At peak, Claude was writing 1,300 lines of code per minute — but engineering challenges piled up fast: multiple Claude instances trampling each other's git state, disk space running out, tests exhausting TCP ports, and tens of thousands of spawned processes crashing machines.

cgroups (Control Groups) is a Linux kernel mechanism for limiting, isolating, and accounting for the resource usage (CPU, memory, disk I/O, network bandwidth, etc.) of groups of processes. It is one of the underlying foundations of container technologies like Docker and Kubernetes. systemd-run is a systemd command-line tool that wraps arbitrary commands as temporary systemd service units, with direct cgroup constraints. Jared used systemd-run with cgroups to limit memory and CPU, isolate process namespaces, and create independent resource boundaries for each AI instance — effectively using lightweight containerization to solve the novel DevOps problem of "AI agent cluster resource management." He even gave Claude a rule: "If you need a paragraph to explain why a workaround is acceptable, the code is wrong — go fix the code."

The final result: 6,502 commits, 1.78 million lines of code written, 11 days — from first run to 100% test pass across all platforms.

doesn't

Costs, Outcomes, and Industry Implications

The Real $165,000 Bill

The token consumption before merging was staggering: 5.9 billion uncached input tokens, 690 million input tokens, and 72 billion cached reads — approximately $165,000 at API prices.

Large language model APIs typically charge per token, where a token is the basic unit of text the model processes — roughly 4 characters in English or about 1.5 Chinese characters. Anthropic prices Claude's input and output tokens separately and has introduced a Prompt Caching mechanism: when the same system prompt or context appears repeatedly across multiple requests, the cached version is charged at a significantly lower rate than new uncached input tokens. The dramatic ratio of "72 billion cached reads" vs. "5.9 billion uncached inputs" in Bun's migration reflects prompt caching working at massive scale — the 50 workflows repeatedly referenced the same porting guide, coding standards, and context over 11 days, achieving extremely high cache hit rates. This is also one of the key reasons the total cost was kept to $165,000.

That number sounds striking, but Theo offered three layers of analysis:

  1. Compare to human cost: If done by 3 engineers over 1 year, the cost would be approximately $600,000 — and all other development would be forced to halt during that time, making it practically infeasible.
  2. It wouldn't have happened at all: If it took a year, this project would never have been started — it only makes sense as a short-term experiment. So this isn't "$600K vs. $165K" — it's "never doing it vs. $165K."
  3. Prices keep falling: This was the most expensive this migration will ever be. As cheaper models continue to emerge, the cost of equivalent intelligence will only continue to drop.

Actual Quality Outcomes

The Rust version's performance validated the migration: only 19 regression bugs were introduced (most stemming from cases where two languages share the same syntax but have different semantics), while 128 bugs that existed in the Zig version were simultaneously fixed. Memory usage dropped significantly — a certain build process that leaked nearly 7 GB of memory after 2,000 runs in Zig now leaks only about 600 MB in Rust. Additionally, binary size shrank by 20% and performance improved by 2–5%. Currently, only 4% of the code lives in unsafe blocks, and 78% of those unsafe blocks are a single line (typically C++ pointer or C library calls).

A Public Dispute Between Key Figures

Jared's technical blog remained gracious toward Zig, but what truly ignited controversy was a sharply worded response published by Zig language creator Andrew Kelly. Kelly attributed the migration to "a difference in values" and "a breakdown in the relationship," leveling numerous personal criticisms at Jared's management style and engineering practices. Theo pushed back strongly, particularly against Kelly's claim that "a solid test suite is sufficient to catch all bugs" — which entirely ignores the memory safety guarantees that a borrow checker provides that unit tests simply cannot. This dispute also reflects a broader reality: when a language's flagship project chooses to leave, the public reaction of community leaders can have lasting consequences for the language's ecosystem.

audience

A New Engineering Paradigm Is Taking Shape

Setting aside the personal disputes, Bun's rewrite provides an extremely valuable technical reference. It demonstrates that with three key pillars — a language-agnostic test suite (with millions of assertions), adversarial multi-model review, and loop engineering — AI agents can now reliably execute large-scale code migration tasks.

The more important mindset shift is this: when something goes wrong, don't manually fix the code — fix the process that generates the code. "Agents stomping on each other" is a novel engineering problem that will likely become one of the core challenges to solve in the next phase of agentic programming.

As Theo put it, not long ago it would have been unimaginable to migrate such an important project to an entirely new language for under $200,000 — and this is only the beginning of what AI engineering can do.

Key Takeaways

#Claude Code#AI-assisted programming#Bun rewrite#Zig to Rust migration#agentic AI#dynamic workflows#large-scale code migration#Rust borrow checker#AI coding agent
Share:

Related articles