anthropics/code-migration-kit-with-claude-code
Python
Captured source
source ↗anthropics/code-migration-kit-with-claude-code
Description: Prompts, templates, and scripts for running large-scale language migrations with Claude Code
Language: Python
License: NOASSERTION
Stars: 16
Forks: 0
Open issues: 0
Created: 2026-07-08T14:22:06Z
Pushed: 2026-07-08T15:00:59Z
Default branch: main
Fork: no
Archived: no
README:
Claude Code Migration Kit
A starter kit for running large-scale language migrations with Claude Code: the prompts, templates, and scripts behind the process described in How Anthropic runs large-scale code migrations with Claude Code.
This kit defaults to structure-preserving migrations — same architecture, same data structures, new language. That's the case where the process below is mechanical enough to template. If you're redesigning as you migrate, read [If you're redesigning](#if-youre-redesigning) first: parts of this kit change, and one part becomes invalid.
> Provenance: these prompts are reconstructions — generalized and reviewed > against real production migrations, including Bun's 1M+ line Zig→Rust port, > not transcripts. The real artifacts were messier and more specific: the Bun > port's "prompt" was a 576-line rulebook > (PORTING.md) > and a one-sentence kickoff.
> Status: Reference code. This repo is a companion to the blog post and is > not actively maintained. Issues and PRs are not monitored.
Quick start
1. Clone the kit inside (or adjacent to) the repo you're migrating: git clone ./migration-kit. 2. Copy or @-import the kit's CLAUDE.md into the target repo's CLAUDE.md before the six steps below begin — it's the operating manual every session reads. 3. Optional: install the skill — cp -r migration-kit/skill ~/.claude/skills/code-migration, then replace [kit path] inside the installed SKILL.md. 4. Open Claude Code in the target repo and paste prompts/00-feasibility.md with its placeholders filled. 5. Make sure you have a judge before Step 1. If your existing test suite hits the public surface (or already lives in a third language), it's your judge — carry it into Step 6. If it imports internals that die with the old language, run prompts/00b-judge-setup.md to build a portable parity harness and validate it (against the original *and* against deliberately broken code) before any translation. No judge, no exit condition. 6. Before any translation fan-out (prompt 03 onward): copy templates/settings.json to the target repo's .claude/settings.json (see templates/settings.README.md) — installed by you before prompt 03 (Step 2's pilot needs the denies live), active through Step 4 (prompt 05), test denies re-activated for Step 6's fix loops. Prompts 03 and 04 verify it exists and stop without it — in one early test run this step was silently skipped and nothing caught it. 7. Then work prompts/01–06 in order, one gate at a time.
Should you migrate at all?
Start with prompts/00-feasibility.md. Paste it into Claude Code in your repo. It produces a read-only report: the case for leaving, three committed calls (structure-preserving or redesign, what verification costs, whether your tests survive), a sketch of the six steps for your repo, and a verdict. "Don't migrate" is a valid outcome. Nothing else in this kit matters until that report says go.
The six steps
Every step below follows the same doctrine: you don't fix the code — you fix the process that produced the code. Individual failures get burned down by fixer agents; recurring failures indict a rule, and the rule gets amended.
| Step | What happens | Kit artifact | |---|---|---| | 1. Create the map and the rules | Dependency map orders the work; gap inventory traces what the target language demands; the rulebook decides every translation question once | scripts/depmap_*, prompts/01, prompts/02, templates/RULEBOOK.md, templates/inventory.tsv | | 2. Stress-test the rules | Dual-translation bakeoff + pilot run on a handful of nasty files; the only surviving output is rule changes | prompts/03-stress-test.md | | 3. Translate everything | Implementer + two adversarial reviewers + fixer per unit, fanned out over a mechanical queue; the compiler waits | prompts/04-translation-kickoff.md, scripts/queue_runner.mjs | | 4. Compile | One survey build grades everything; error list becomes a machine queue sliced by module; fixers work without compiler access | prompts/05-survey-build.md, templates/settings.json (the bans) | | 5. Run it | Hello world, then smoke tests — the cheap end-to-end proof before the expensive one | — | | 6. Match behavior | Inherited test suite burndown, or build a parity referee against the old code | your existing test suite is the artifact; prompts/06-post-parity.md after the gate |
Step 1 — Create the map and the rules
Three artifacts, built in parallel, audited together:
1. The rulebook (templates/RULEBOOK.md — copy it to migration/RULEBOOK.md in the target repo): every decision a translator could make two ways, decided once. The meta-rule: *if two agents could answer differently, it goes in the rulebook.* Draft it in a conversation with Claude, then have agents survey the codebase for the facts ("how many struct fields," "how many uses tree-wide") and adversarial reviewers audit it — one mistake class each. 2. The dependency map (scripts/depmap_*.py|.mjs + prompts/01): a deterministic script, not agent judgment. Orders the work, finds the cycles — at file granularity AND at the target's package granularity. (Bun's port had a clean file graph and still hit ~16K compile errors from package-level cycles nobody had checked.) 3. The gap inventory (prompts/02 + templates/inventory.tsv): one flat table of every site where the target language demands something the source let you keep in your head — ownership, lifetimes, nullability, interface contracts. Implementers grep it; nobody reads it top to bottom.
The sign-off gates in these prompts work like this: a workflow runs its phase to completion, returns the evidence, and exits. Your sign-off is the act of kicking off the next one. Every queue is defined by what exists on disk, so stopping is free and resuming is a re-invocation, not a recovery. When a prompt says "use a workflow," it means: run the phase as parallel subagents that complete and stop at the gate — in stock Claude Code, that's a Task/Agent...
Excerpt shown — open the source for the full document.