How Claude Code Rewrote Bun in Rust: A Six-Step Guide to Large-Scale Code Migration

Large programming-language migrations used to be the kind of project engineering teams postponed for years. They were expensive, disruptive, and risky. A company could spend several quarters maintaining two implementations and still end up with a replacement that behaved differently from the original. Claude Code is beginning to change that calculation. Anthropic recently published the process it uses for large-scale code migrations with AI agents. The most striking example is Bun creator Jarred Sumner’s migration of Bun’s core from Zig to Rust. In less than two weeks, Claude Code workflows generated more than one million lines of code, while Bun’s existing test suite passed in continuous integration before the merge. The project was not completed by asking a model to “rewrite Bun in Rust” and waiting for a perfect answer. It relied on a carefully designed system of rulebooks, dependency maps, mechanical queues, adversarial reviewers, compilers, smoke tests, and behavior-parity checks.

发布于 2026年7月19日generalGEO 评分: 07 次阅读
图片为“Claude Code 迁移指南”封面,背景为深蓝色,带有橙色和蓝色的光晕效果。左侧有“Claude”字样,右侧是“Claude Code 迁移指南”文字,其中“迁移”为橙色。画面下方有代码编辑器界面的图标,以及指向右侧的橙色箭头。该图片与文档中介绍 Claude Code 帮助 Bun 从 Zig 迁移到 Rust 的迁移指南内容相关,作为封面图,直观呈现了主题。

How Claude Code Rewrote Bun in Rust: A Six-Step Guide to Large-Scale Code Migration

Introduction

Large programming-language migrations used to be the kind of project engineering teams postponed for years. They were expensive, disruptive, and risky. A company could spend several quarters maintaining two implementations and still end up with a replacement that behaved differently from the original.

Claude Code is beginning to change that calculation.

Anthropic recently published the process it uses for large-scale code migrations with AI agents. The most striking example is Bun creator Jarred Sumner’s migration of Bun’s core from Zig to Rust. In less than two weeks, Claude Code workflows generated more than one million lines of code, while Bun’s existing test suite passed in continuous integration before the merge.

The project was not completed by asking a model to “rewrite Bun in Rust” and waiting for a perfect answer. It relied on a carefully designed system of rulebooks, dependency maps, mechanical queues, adversarial reviewers, compilers, smoke tests, and behavior-parity checks.

The central lesson is straightforward: for a migration this large, the developer should not spend most of their time repairing individual files. They should improve the process that generates, reviews, and verifies those files.

Bun’s Creator Used AI to Rewrite More Than One Million Lines of Code

Jarred Sumner originally built Bun in Zig. The language gave a solo developer low-level control and C-like performance without the full complexity of a larger systems-language ecosystem.

That choice helped Bun move quickly in its early years. Sumner has said that he wrote the first version in roughly one year from a small apartment in Oakland, before modern coding models were available.

By 2026, Bun had become a widely used JavaScript and TypeScript runtime, package manager, test runner, and bundler. Its command-line tool was receiving tens of millions of monthly downloads, and products including Claude Code depended heavily on Bun.

Growth also made old engineering trade-offs harder to ignore.

Bun combines a garbage-collected JavaScript engine with manually managed native memory. In Zig, developers must explicitly reason about allocation, cleanup, error paths, and object lifetimes. Bun’s team had invested heavily in sanitizers, fuzzing, safety-checked builds, and memory-leak tests, but use-after-free errors, double frees, leaks, and lifetime mistakes still appeared.

Rust offered a different foundation. Its ownership system, borrow checker, and automatic cleanup could turn many runtime memory problems into compile-time errors.

Historically, that benefit would not have justified a complete rewrite. Bun contained hundreds of thousands of lines of Zig, plus extensive native integrations. A traditional rewrite could have consumed a small engineering team for a year or more while slowing feature work and security fixes.

Claude Code made a full mechanical migration appear possible.

From Zig to Rust in 11 Days

Sumner used a prerelease version of Claude Fable 5 and Claude Code dynamic workflows to carry out the migration.

The main writing and review process ran continuously for 11 days. Around 50 dynamic workflows handled different stages, including:

  • Creating a Zig-to-Rust porting guide
  • Mapping memory lifetimes
  • Translating .zig files into .rs files
  • Reviewing each generated file
  • Fixing compiler errors
  • Restoring individual Bun commands
  • Running the complete test suite
  • Refactoring and cleaning up the generated code

At peak throughput, the workflows produced roughly 1,300 lines of code per minute. Each generated unit was checked by two independent adversarial reviewers before a fixer applied confirmed changes.

The final pull request added more than one million lines across over 2,000 changed files.

How Claude Code Rewrote Bun in Rust: A Six-Step Guide to Large-Scale Code Migration — illustration 1

Before the merge, Bun’s existing test suite passed in CI. Nineteen regressions appeared afterward, and Anthropic reported that all of them were subsequently fixed. The Rust port had already shipped inside Claude Code in June 2026.

This result was not proof that the first million generated lines were correct. Sumner explicitly noted that the earliest translated output did not work. The successful part was the feedback system that gradually turned non-working output into compiled, tested, behavior-compatible code.

The Migration Cost About $165,000 at API Prices

The Bun migration consumed approximately:

  • 5.9 billion uncached input tokens
  • 690 million output tokens
  • About $165,000 at API pricing

That is a substantial amount of money. It is also far below the cost of a traditional multi-year migration involving several full-time engineers.

Anthropic estimated that million-line migrations previously could cost roughly $3 million to $4 million in engineering resources over four years. AI changes the business case because the migration no longer needs to solve an existential problem to justify the expense.

A persistent memory bug, an aging language ecosystem, an expensive build process, or a recurring maintenance bottleneck may now be enough to make a migration worth evaluating.

The comparison should still be made carefully. Token cost is not the entire project cost. Teams also need human planning, infrastructure, testing, code review, security work, and post-merge maintenance.

Why Bun Moved from Zig to Rust

The migration was motivated primarily by reliability rather than raw speed.

Bun already performed well in Zig. The problem was the burden of safely coordinating manually managed native memory with a garbage-collected JavaScript runtime.

Common failure categories included:

  • Use-after-free bugs
  • Double-free bugs
  • Memory leaks on uncommon error paths
  • Invalid pointers caused by re-entrant callbacks
  • Cleanup code that was skipped
  • Lifetime assumptions that were difficult to enforce consistently

In safe Rust, many of these mistakes cannot compile. Values have explicit ownership, cleanup is tied to object lifetime, and the compiler checks references before the program runs.

The migration aimed to preserve Bun’s existing architecture, data structures, behavior, and performance. It was intentionally closer to a mechanical port than a complete redesign.

That decision was important. Redesigning the system and changing the language at the same time would have made behavior comparison much harder.

A Second Case: 165,000 Lines of Python Became TypeScript

Jarred Sumner was not the only Anthropic engineer using Claude Code for a major migration.

Mike Krieger, co-lead of Anthropic Labs and a co-founder of Instagram, migrated an internal Python codebase into approximately 165,000 lines of TypeScript over one weekend.

The main migration consumed around 27 million tokens and involved:

  • Hundreds of agents
  • Eight phase gates
  • Three rounds of adversarial review
  • A final parity check
  • Command-by-command output comparison with the Python version
  • AI-generated end-to-end tests

The original tool needed to be delivered as a single binary. With the Python toolchain, compilation took about eight minutes per platform, and the complete build matrix delayed each release by around 30 minutes.

After the TypeScript migration:

  • Compilation took roughly two seconds
  • The binary started about six times faster
  • A separate deployment pipeline could be retired

Krieger did not rely on an existing comprehensive cross-language test suite. Instead, Claude created a parity harness covering seven real-world scenarios, then compared the output of the old and new implementations.

Claude also designed additional end-to-end tests and ran them overnight for four consecutive nights, fixing failures and repeating the process. This uncovered small behavioral differences that the original scenarios had not anticipated.

Why Large Code Migrations Work Well with AI Agents

Large migrations look intimidating to people because they involve huge numbers of repetitive changes. Those same characteristics can make them suitable for agent workflows.

The Work Can Be Parallelized

A large repository can often be divided into files, packages, crates, modules, or dependency groups. Separate agents can process independent units at the same time.

The dependency map determines which units can move in parallel and which must wait.

The Existing Code Is the Specification

The original implementation already contains the required behavior, edge cases, data structures, and integration details.

The model does not need to invent the product. Its job is to preserve the existing system in a new language or framework.

Tests Provide an Objective Judge

Agents work better when they can evaluate their output mechanically.

A compiler, test suite, output diff, benchmark, or parity harness gives the system a concrete signal. The agent can continue working against that signal without requiring a human to judge every intermediate attempt.

The Queue Can Generate Itself

A compiler error becomes the next task. A failed test becomes the next task. A crash becomes the next task.

This turns a large migration into a queue that can be repeatedly reduced.

Repeated Failures Can Improve the Rules

When reviewers find the same problem in many files, the best solution is not to patch each file manually.

The rulebook should be updated, and the affected batch should be regenerated. This prevents the same error from returning in later work.

The Core Principle: Fix the Loop, Not the Individual File

The most important idea in Anthropic’s process is to treat generated code as the output of a system.

Suppose 200 translated files contain the same ownership mistake. Manually repairing those files may solve the visible errors, but the workflow can produce the same mistake again.

A stronger approach is:

  1. Identify the repeated failure pattern.
  2. Determine which migration rule caused it.
  3. Update the rulebook.
  4. Regenerate only the affected files.
  5. Run the reviewer and verification loops again.

The code improves because the production process improves.

This resembles ordinary software engineering. A recurring production bug should lead to a better test, type rule, static check, or process—not just another isolated patch.

Prerequisite: Build a Reliable Judge

Before beginning a large migration, define how the team will prove that the new implementation is correct.

Without a judge, there is no reliable completion condition.

The judge must evaluate the original and target implementations on equivalent terms. Existing tests may depend on private functions or language-specific internals that disappear during the port.

Anthropic recommends three preparation tasks:

  1. Categorize existing tests. Separate tests that exercise public behavior from tests tied to internal implementation.
  2. Rewrite tests for portability. Convert externally observable behavior into assertions that can run against both systems.
  3. Validate the judge. Confirm that the original implementation passes, then deliberately break the program and confirm that the judge fails.

A test suite that cannot detect known breakage is not a useful migration judge.

Bun had a major advantage: much of its test suite was written in TypeScript rather than Zig, so the same suite could test the Rust implementation.

For projects without this advantage, a parity harness can compare real inputs and outputs between the two versions.

Anthropic’s Six-Step Code Migration Framework

Anthropic generalized the lessons from these projects into a six-step process.

How Claude Code Rewrote Bun in Rust: A Six-Step Guide to Large-Scale Code Migration — illustration 2

Step 1: Create the Rulebook, Dependency Map, and Gap Inventory

The first stage creates the shared documents every later agent will follow.

Build the Rulebook

The rulebook defines how concepts in the source language map to the target language.

For a structure-preserving migration, it may contain:

  • Type mappings
  • Error-handling conventions
  • Naming rules
  • Memory and ownership rules
  • Standard library substitutions
  • Concurrency patterns
  • File and module layout
  • Rules for foreign-function interfaces
  • Patterns that require human review

For a redesign, the rulebook becomes closer to an architecture document.

Jarred Sumner developed Bun’s porting guide through conversations with Claude and human review. The final artifact was hundreds of lines long.

Create the Dependency Map

The repository must be divided in an order that respects dependencies.

A deterministic script can inspect imports, manifests, build files, and symbol relationships to produce the map. The result helps the orchestrator decide which files can be translated independently and which should be processed together.

Write the Gap Inventory

The source and target languages do not enforce the same rules.

For Zig to Rust, memory ownership was a major gap. For Python to TypeScript, implicit object shapes and interfaces had to become explicit contracts.

The gap inventory records places where simple translation is insufficient.

It should identify:

  • Hidden source-language assumptions
  • Missing target-language abstractions
  • Runtime behavior that must become explicit
  • Unsupported libraries
  • Platform-specific code
  • Unsafe boundaries
  • Areas requiring redesign or manual decisions

The rulebook should be created before the gap inventory, because the inventory is partly defined by what the normal rules cannot handle.

Step 2: Stress-Test the Rules

Do not immediately translate thousands of files.

Run a small, disposable pilot on a few difficult and representative files. The purpose is to expose weaknesses in the rules before those weaknesses spread across the repository.

In Bun’s pilot:

  1. One agent translated three files using the rulebook.
  2. Another translated the same files as an experienced Rust engineer.
  3. A comparison agent inspected the differences.
  4. Reviewers identified missing or incorrect migration rules.
  5. The translated files were discarded.

The output of this stage is a better rulebook—not production code.

For a redesign migration, the equivalent test is to attack the design document with adversarial reviewers, then perform a disposable end-to-end run.

Step 3: Translate Everything

Once the rules survive the pilot, the repository can be processed through a parallel queue.

A typical unit uses:

  • One implementer
  • Two independent adversarial reviewers
  • One fixer
  • A mechanical queue
  • A shared rulebook
  • A shared gap inventory

The queue should be resumable. A script should be able to determine which work is complete by checking files or recorded artifacts rather than depending on one agent’s memory.

Agents should flag unresolved work consistently, for example:

TODO(port): explain why this section could not be translated safely

Do not use the most expensive model for every unit. Smaller capable models can handle high-volume translation, while stronger models are reserved for reviewers, architectural choices, and rule changes.

Step 4: Compile

The first full build turns compiler errors into a structured work queue.

Depending on build cost, the compiler may run inside each agent loop or through a separate orchestrator.

For Bun, compiling the whole workspace was expensive, so Claude agents did not run cargo freely during file translation. Instead:

  1. An orchestrator ran the compiler.
  2. Errors were written into a shared list.
  3. The list was grouped by module or root cause.
  4. Fixer agents handled groups in parallel.
  5. Reviewers checked the fixes.
  6. The orchestrator rebuilt the project.

This prevents dozens of agents from launching the same expensive build at the same time.

Systemic compiler errors should update the rules. For example, a target language may reject cyclic dependencies that the source compiler tolerated lazily. That is a process-level issue, not merely a list of unrelated file errors.

Step 5: Run the Program

A successful compile only proves that the target language accepts the code.

The next stage uses basic execution and smoke tests to find crashes, initialization failures, missing resources, invalid assumptions, and broken integrations.

Failures should again be grouped by cause.

If 40 smoke tests fail because of one incorrect initialization pattern, fix the migration rule and regenerate the affected code rather than assigning 40 isolated patches.

Step 6: Match the Original Behavior

The final gate is behavioral parity.

Run the portable test suite, parity harness, output comparisons, and relevant benchmarks against both codebases.

For each failure:

  1. Give a fixer access to the failing evidence and both implementations.
  2. Ask the fixer to identify the behavioral difference.
  3. Have adversarial reviewers inspect the proposed change.
  4. Batch expensive rebuilds through one build process.
  5. Re-run the affected tests.
  6. Escalate repeated failures into rule changes.

The original codebase remains the ground truth unless the project explicitly intends to change behavior.

A missing test suite does not make this step optional. Teams can use Claude to create an external parity harness from real scenarios and then validate that harness against deliberately broken behavior.

Quick Start with Anthropic’s Migration Kit

Anthropic released a public starter kit containing generalized prompts, templates, and scripts based on the migration process.

The repository is reference material rather than a fully managed migration product. Its prompts are reconstructed templates, not exact transcripts from the Bun project.

1. Install Claude Code

On macOS or Linux:

curl -fsSL https://claude.ai/install.sh | bash

On Windows PowerShell:

irm https://claude.ai/install.ps1 | iex

Review remote installation scripts and your organization’s security policies before running them.

2. Clone the Migration Kit

From the repository you want to migrate:

git clone https://github.com/anthropics/code-migration-kit-with-claude-code.git ./migration-kit

3. Add the Migration Skill

This optional step copies the migration skill into the local Claude Code skills directory:

cp -r migration-kit/skill ~/.claude/skills/code-migration

Update the kit path inside the installed SKILL.md as described in the repository.

4. Run the Feasibility Assessment

Start with the kit’s read-only feasibility prompt:

prompts/00-feasibility.md

The result should answer three questions:

  • Should the project migrate at all?
  • Is the migration structure-preserving or a redesign?
  • Can the original and target implementations be judged fairly?

“Do not migrate” is a valid result.

5. Prepare the Judge and Safety Rules

Before translation fan-out:

  • Build or validate the cross-language judge.
  • Copy the recommended Claude settings into the target repository.
  • Deny destructive or expensive commands where appropriate.
  • Confirm the source repository has recoverable backups.
  • Use isolated branches, controlled worktrees, and least-privilege credentials.

Then run the migration prompts in order rather than skipping directly to mass translation.

What Went Wrong During Bun’s Early Attempts

The Bun migration was not smooth from the first run.

When many agents began working in one repository, their Git operations interfered with each other. One agent ran git stash, another used git stash pop, and another reset the working tree.

Sumner changed the workflow so agents could not freely run destructive Git commands. He later divided the work into four workflow shards with separate worktrees, each coordinating multiple agents.

This example highlights a critical point: agent permissions must match the workflow design.

A coding agent with broad shell access can:

  • Delete or overwrite work
  • Reset uncommitted changes
  • Trigger expensive builds repeatedly
  • Modify unrelated files
  • Leak secrets through commands or logs
  • Interfere with other agents

The orchestration layer must restrict commands, define file ownership, serialize expensive operations, and make recovery simple.

Best Practices for AI-Assisted Code Migrations

Anthropic’s published lessons can be reduced to several practical rules.

Do Not Follow a Generic Guide Blindly

Every codebase has different build systems, test coverage, runtime behavior, deployment constraints, and risk tolerance.

Use the six-step framework as a starting point, then ask Claude to adapt it to the actual repository.

Focus on Patterns, Not Individual Failures

Fixer agents can process individual failures. Human attention is more valuable when it identifies repeated patterns, missing rules, unsafe assumptions, and architectural problems.

Make Review Adversarial

The implementing agent should not be its own only reviewer.

Give reviewers separate context and tell them to assume the generated code is wrong. Their job is to find reasons it fails, drifts, or violates the rulebook.

Make Verification Mechanical

Use compilers, tests, linters, output diffs, benchmarks, and deterministic scripts as judges.

A subjective “looks correct” review cannot safely validate a million-line change.

Use Different Models for Different Roles

High-volume translation can be assigned to smaller or cheaper models. The strongest models should handle rule creation, architecture, ambiguous failures, and review.

Spend Human Time Early

The highest-value human work happens before mass generation:

  • Defining the business case
  • Building the judge
  • Writing the rulebook
  • Mapping dependencies
  • Auditing the pilot
  • Setting permissions and boundaries

Once those foundations are reliable, much of the remaining work becomes a mechanical queue.

Keep the Queue Resumable

A migration that runs for days must survive crashes, restarts, model failures, and infrastructure interruptions.

Completion should be derived from durable artifacts on disk, commits, test records, and queue state—not from one long conversation.

Results After the Bun Migration

Anthropic reports that Bun’s Rust-based code is now running in production.

The migration did not eliminate every trade-off. Roughly 4% of the Rust code remained inside unsafe blocks, mainly for small pointer operations at C and C++ boundaries.

However, the new implementation produced measurable improvements:

  • Detectable memory leaks were fixed
  • One repeated-build benchmark dropped from 6,745 MB of memory to 609 MB
  • The binary became 19% smaller on Linux and Windows
  • Cross-language optimization improved selected workloads by roughly 2% to 5%

These results show why the migration mattered. The goal was not to produce a large amount of AI-written code. It was to produce a system that was safer, smaller, and easier to maintain while preserving behavior.

When an AI Migration Is a Good Fit

A large migration may be suitable for an agent workflow when:

  • The original codebase is available as a complete specification
  • Behavior can be checked externally
  • Tests or parity scenarios can be created
  • Work can be divided into repeatable units
  • The target language has clear benefits
  • The organization can tolerate a large experimental branch
  • Human experts can review architecture and edge cases
  • The tool environment can be restricted and audited

It may be a poor fit when:

  • The original behavior is poorly understood
  • There is no way to verify correctness
  • The project mixes migration with a complete product redesign
  • Regulatory approval requires manual validation of every change
  • The code contains secrets or systems that cannot safely be exposed
  • The team lacks ownership after the AI-generated code is merged

The ability to generate a million lines quickly does not make a migration automatically sensible.

FAQ

Did Claude Code really rewrite Bun from Zig to Rust?

Yes. Jarred Sumner used Claude Code dynamic workflows and a prerelease Claude model to migrate Bun’s core from Zig to Rust. The process generated more than one million lines of code in less than two weeks, followed by compilation, testing, review, and post-merge fixes.

How much did the Bun migration cost?

Anthropic reported approximately 5.9 billion uncached input tokens and 690 million output tokens. At API pricing, the estimated model cost was about $165,000, excluding human labor and infrastructure.

Did all tests pass before the migration was merged?

Anthropic says Bun’s existing test suite passed in CI before the merge. Nineteen regressions were found afterward, and all were later fixed.

Why did Bun move from Zig to Rust?

The main goal was to improve memory safety and reduce recurring lifetime, cleanup, use-after-free, double-free, and leak problems. Rust’s ownership and type systems can catch many of these issues during compilation.

Can Claude Code migrate any codebase automatically?

No. Successful migrations require a strong judge, explicit rules, dependency analysis, controlled permissions, repeatable queues, adversarial review, and human oversight. Some projects should not be migrated at all.

What is adversarial code review?

An adversarial reviewer receives the generated change in a separate context and is instructed to find defects rather than approve it. The implementer and reviewer have different roles, which reduces the risk of the author simply defending its own output.

Do I need an existing test suite?

A strong existing suite is ideal, especially when it tests public behavior independently of the implementation language. When that is not available, teams can build a parity harness that compares real scenarios and outputs between the old and new systems.

Is Anthropic’s migration kit the exact workflow used for Bun?

No. Anthropic describes the repository as a generalized and reconstructed starter kit. The actual Bun migration used more specific artifacts, including a long project rulebook and custom dynamic workflows.

Related Tools

  • Claude Code: Anthropic’s agentic coding tool for working with repositories, terminals, tests, and development workflows.
  • Bun: A JavaScript and TypeScript runtime, package manager, bundler, and test runner.
  • Rust: A systems programming language focused on performance, type safety, and memory safety.
  • Zig: A low-level programming language that emphasizes explicit control and simple language semantics.
  • GitHub: The source-control and collaboration platform used to manage the Bun migration pull request and Anthropic’s migration kit.
  • Claude Code Modernization Plugin: Anthropic’s official plugin for assessing and modernizing legacy systems.

Related Links

Summary

Claude Code did not make Bun’s migration successful by generating a perfect million-line rewrite in one attempt. The project worked because the team built a disciplined production system around the model: a rulebook, dependency map, gap inventory, pilot, parallel translation queue, adversarial review, compiler loop, smoke tests, and behavior-parity checks.

The same approach helped Anthropic migrate a large Python codebase to TypeScript over a weekend. In both cases, objective verification was more important than raw generation speed.

AI can significantly reduce the cost and duration of large migrations, but only when the process is resumable, permissions are controlled, and repeated defects improve the rules that generated the code.

The real breakthrough is not that AI can write one million lines—it is that a well-designed loop can repeatedly generate, challenge, test, and correct those lines until the new system behaves like the old one.