Big migrations — Vue 2 to Vue 3, React class components to hooks, JavaScript to TypeScript, Next.js Pages Router to App Router — used to mean three weeks of mechanical edits plus a week of bug hunting. Asking a model to “migrate this repo” in one prompt produces a plausible-looking codebase that does not run. This workflow pairs the model’s mechanical speed with your code-review judgment: a hand-built reference file, pattern propagation, a codemod for the long tail, then an official-checklist review. On a real React class-to-hooks migration of ~50 components, it cuts a three-week job to about three days while keeping the test suite green at every commit.
TL;DR
- Never one-shot the whole repo. Cut the migration into chunks with a pass/fail you can verify; failures stop at one file, not 200.
- The pipeline: official-guide summary → 1 reference file by hand + AI → 5-10 files using that reference → codemod for the trivial tail → official-checklist review.
- Use official codemods where they exist (
@vue/compat,npx @next/codemod, Airbnbts-migrate); use AI for the judgment cases codemods can’t decide. - As of June 2026, Claude Opus 4.7 and Gemini 3.1 Pro both hold a 1M-token context — large enough to feed the reference file and the target file in one prompt, which is where consistency comes from.
- Requirement: test coverage above ~50% on the files you touch. Without tests, every step is a faith move.
Who this is for and when it fits
This is for developers facing a multi-week migration who want AI to do the mechanical bulk without producing garbage, and for tech leads turning a migration into a real estimate. It works best on codebases of 50-1,000 files, where hand-migrating is too slow but a pure codemod misses the judgment cases.
Reach for it when the migration has a clear official upgrade path (Vue, React, Next.js, Angular, Svelte) and multiple files change in the same way. The trigger test: name three files, and they would all change identically. It also fits typed-language moves (JS to TS, Python 2 to 3) that have official codemods but still need cleanup.
Skip it when the migration crosses paradigms — jQuery to React, REST to GraphQL — where there is no mechanical translation; there, AI is a learning aid and the architecture is yours. Also skip it if the code has no test coverage, because you cannot validate a single step.
Pick the right tool before you prompt
Most migrations have an official mechanical tool. Use it for the bulk; reserve the model for cases the tool flags or can’t decide. This table reflects the state of these tools as of June 2026.
| Migration | Official mechanical tool | What it does NOT cover (AI’s job) |
|---|---|---|
| Vue 2 → Vue 3 | @vue/compat migration build + the guide at v3-migration.vuejs.org | Composition API rewrites, v-model reworks, render-function changes |
| Next.js Pages → App Router | npx @next/codemod (e.g. next-async-request-api for async cookies()/headers()/params) | Restructuring routes, splitting client/server components, data-fetching rewrites — no single codemod does the whole move |
| JS → TypeScript | Airbnb ts-migrate (Airbnb reports 50k+ LOC, 1,000+ files in a day) | Real types beyond any, and class-to-hooks (ts-migrate doesn’t touch hooks) |
| React class → hooks | None official | The entire conversion — lifecycle to useEffect, state to useState/useReducer |
| Bulk renames (props, imports, deprecated hooks) | jscodeshift / ts-morph / ast-grep | Anything needing a judgment call mid-rename |
On codemod engines: jscodeshift (Meta) is the classic JS/TS transformer; ts-morph wraps the TypeScript compiler API so it can reason about real types during a transform; ast-grep (and the newer jssg authoring layer built on it) is faster and polyglot, and is the one most actively recommended for new codemods in 2026. Pick ts-morph when type information drives the change; pick ast-grep for speed and non-JS languages.
For the framework specifics, see the AI dependency upgrade workflow for keeping the migration on a pinned, reproducible version, and the AI refactor workflow for the file-level review discipline this borrows from.
Before you start
- Confirm test coverage above ~50% on the files you’ll touch. If it’s low, write characterization tests on the most-edited files first.
- Pin the exact version pair. “Vue 2.7 to Vue 3.5” is a different migration than “Vue 2.0 to Vue 3.5”; the model needs the real starting point. (Vue 2 has been end-of-life since December 31, 2023, so “stay on 2” is not an option for new security fixes.)
- Read the official migration guide once, end to end. The model can summarize it, but you need to be able to catch a wrong summary.
- Branch clean, with no other refactors in flight. Mixing the migration with unrelated changes destroys your ability to bisect.
The workflow, step by step
- Ground the model in the official guide. First chat: paste the official migration-guide URL for your exact version pair and ask for the 5-10 most common mechanical changes. Pinning the URL keeps the model on the official path instead of two-year-old blog folklore — important because frontier models were trained before some guides were finalized.
- Build one reference file by hand + AI. Pick a medium-complexity file from the middle of the codebase, not the simplest one. Prompt:
Apply migration changes 1-5 to this file. Output:
1. The full migrated file
2. A diff against the original
3. A list of any judgment calls you made
Do not refactor unrelated code. Do not rename variables that
do not need renaming. Do not "improve" the file.
- Review and lock the reference. Review the diff line by line. Run tests on this file only. Fix issues yourself or with one more focused prompt. This file is now your reference implementation — commit it alone.
- Propagate the pattern. Next chat: “Here is the reference migration of File A (paste). Apply the same pattern to File B (paste). Match the style of File A’s migration exactly.” Feeding both files in one prompt is why a 1M-token context model matters — the consistency comes from the model seeing the reference, not re-deriving it.
- Repeat for 5-10 files. By the third file you understand the patterns; by the seventh you can spot a wrong suggestion in five seconds. Commit each file individually so bisect works.
- Codemod the long tail. For the 40-200 trivial cases, write a codemod with AI help in jscodeshift, ts-morph, or ast-grep, or run the official one (
npx @next/codemod <transform> <path> --dry --printto preview). Always dry-run, eyeball the diff, then apply. Tests must pass after each batch. - Official-checklist review. Final chat: “Review this branch for any of these official migration items I missed: [paste the guide’s checklist].” Fewer than five missed items is healthy; more means propagation broke silently somewhere — go find the divergence.
A first run that won’t blow up
Pick the smallest non-trivial migration on your roadmap — one feature folder, 10-20 files. Real stakes, small blast radius. Run the full pipeline once and time each phase: guide summary, reference file, propagation, codemod, review. Save the reference-file diff and the codemod script; they become templates for the next migration of the same kind. On the next batch, change exactly one variable — a different model, or more files per propagation prompt — so you can attribute any change in quality.
Quality gates
- Tests pass after every commit. If one commit changed five files and broke, isolate the culprit before moving on.
- The reference file’s diff is reviewable in under 10 minutes. If not, the model added too much; tighten the prompt to forbid unrelated changes.
- The codemod’s dry-run diff is reviewable in under 30 minutes. If not, the codemod is too aggressive — narrow its match.
- The final review surfaces fewer than five missed items. More than five means propagation diverged.
- A
MIGRATION-LOG.md(file, status, notes, blockers) is committed, so a teammate could finish the work if you stopped today.
Which model for migration work
As of June 2026, the practical picks:
| Model | Context window | Why for migrations |
|---|---|---|
| Claude Opus 4.7 | 1M tokens | Strongest at holding consistency across many files and tracking type dependencies across module boundaries; SWE-bench Verified 87.6% |
| Gemini 3.1 Pro | 1M tokens | Same context size at lower API cost ($2/$12 per 1M tokens in/out vs Opus $5/$25); a viable budget alternative for large repos |
| Claude Sonnet 4.6 | 1M tokens | The workhorse for per-file propagation when you don’t need Opus-level judgment |
| GPT-5.5 | App-dependent | Fast and strong on execution; Terminal-Bench 2.0 82.7% makes it good in agentic editors |
The reason context size matters here: propagation works by feeding the reference file plus the target file in one prompt. A 1M-token window lets you also include the relevant type definitions or a second reference, which is what kills inconsistency. If you run migrations inside an editor like Cursor, it routes to Sonnet 4.6, Opus 4.7, GPT-5.5, and Gemini 3.1 Pro, so you can A/B models on the same propagation prompt.
Common mistakes
- One-shot migrating the whole codebase — an untestable wall of changes you cannot bisect.
- Skipping the reference implementation, so every file ends up styled differently and reviewers reject the PR.
- Trusting AI codemods without a dry-run; they edit unrelated code more often than you expect.
- Not running tests between files, letting errors compound silently.
- Mixing the migration with feature work, so a broken commit is impossible to attribute.
- Using a model trained before the framework’s migration guide existed — it gives outdated advice. Pin the guide URL to counter this.
Tips that compound
- Pin the official guide URL in every prompt to keep the model on the official path.
- For mass renames (prop names, deprecated lifecycle hooks, import shapes), a scripted codemod beats AI on accuracy — leave AI for the judgment cases.
- Run the reference file through your team’s normal code review before propagating. A disagreement caught at file 1 saves 50 review comments at file 30.
- Set a “no judgment” rule for the codemod phase: if the codemod can’t mechanically decide, it leaves a
TODOfor hand review rather than guessing. - Build an internal codemod library. The same patterns recur across projects (class to hooks, prop renames, default-to-named imports) — write each once, reuse forever.
FAQ
Codemod or AI per file? Codemod for the mechanical bulk; AI per file for the parts that need judgment. The two are complementary, not either/or.
How long does a real migration take? It scales with size, but AI roughly halves the mechanical 70% of the work. The judgment 30% takes about the same time either way, so budget for that, not for the bulk.
Which model is best for migration? As of June 2026, Claude Opus 4.7 for the hardest consistency-and-judgment work, Gemini 3.1 Pro when you want the same 1M context at lower cost, and Sonnet 4.6 as the per-file workhorse. Any of them beats a small-context model because migrations benefit from seeing the reference and target together.
Should I migrate tests at the same time? Migrate tests in lockstep with their source files. Letting tests and source diverge is how migrations stall — you lose the signal that tells you a step worked.
What if the official guide is incomplete? Search the framework’s GitHub issues for the migration tag. Real-world edge cases live in issues, not in the polished guide.
How do I review 50 AI-migrated files? Group by pattern. Files that share a migration pattern can be reviewed as a batch — read two carefully, skim the rest for deviation.
Related
- AI refactor workflow
- AI dependency upgrade workflow
- Multi-agent coding workflow
- AI monorepo coding workflow
Tags: #AI coding #Tutorial #Workflow