Migrations are where LLMs shine — the work is mechanical, the patterns are documented, and the volume of changes is high. But "just upgrade everything" is how you end up with a half-migrated codebase that neither builds nor runs. The key: understand the breaking changes, scan for affected code, then migrate one breaking change at a time, verifying after each step.
The technique
Phase 1: Research the migration
Before touching any code, have Claude map the migration guide to your codebase.
I want to migrate [library/framework] from [current version] to [target version].
1. Read the official migration guide. (If I provide a URL, fetch it. If not, use your knowledge of the changes between these versions. If you're unsure about specific details, say so — don't guess at API changes.)
2. Summarize every breaking change that affects this project. For each one:
- What changed (old API → new API)
- Search this codebase for every usage of the old API
- Count of affected files
3. List breaking changes in order of dependency — which changes need to happen first because other changes depend on them?
4. Identify any breaking changes that DON'T affect this project (we can skip these)
Output a migration plan as a numbered checklist, ordered by dependency, with file counts.
Phase 2: Migrate incrementally
Work through the checklist one breaking change at a time. After each step, verify the build still works.
Execute step [N] of the migration plan: [description of the change].
Rules:
- Change every instance in the codebase, not just the first one you find
- Run the build after each step to catch issues early
- If a change requires updating tests, update them in the same step
- If a change requires updating types, update them in the same step
- Do not skip ahead to other steps
- If this step is blocked by something unexpected, stop and explain what you found
Phase 3: Verify
After all steps are complete:
The migration is complete. Verify it by:
1. Run the full test suite
2. Run the build
3. Run the linter
4. Search for any remaining references to the old API patterns from the migration guide
5. List any deprecation warnings in the build or test output
Report the results. If anything fails, identify which migration step caused the issue.
Example: Pages Router to App Router
Phase 1 might produce:
Migration plan: Next.js Pages Router → App Router
1. [ ] Create app/ directory with root layout (replaces _app.js and _document.js)
2. [ ] Migrate static pages first (no data fetching) — 2 files
3. [ ] Convert getStaticProps pages to async Server Components — 4 files
4. [ ] Convert getStaticPaths to generateStaticParams — 3 files
5. [ ] Migrate client-side state pages to 'use client' components — 2 files
6. [ ] Move head/meta tags to metadata exports — 5 files
7. [ ] Update next.config.js to remove Pages Router compat flags
8. [ ] Remove pages/ directory
Not affected by this project:
- API routes (none exist)
- Middleware (none exists)
- ISR changes (not used)
When to use it
- Major version upgrades of your framework (Next.js, React, Vue, etc.)
- Library swaps (Moment -> date-fns, Lodash -> native, Jest -> Vitest)
- Language/config migrations (JavaScript -> TypeScript, Webpack -> Vite)
- Infrastructure changes (Heroku -> Vercel, npm -> pnpm)
When NOT to use it
- Patch or minor version upgrades — just bump and run tests
- Migrations with fewer than 5 affected files — just do it manually
- When you don't have a test suite — add tests first, then migrate. Without tests, you won't know if the migration broke behavior.
Tips
- Always create a branch for the migration. If it goes sideways, you can abandon it cleanly.
- The dependency ordering in Phase 1 is critical. Migrating in the wrong order leads to intermediate states where nothing works and you can't tell if your changes are correct.
- Run
git diff --statafter each step to see the scope of changes. If one step touches 30+ files, consider breaking it into sub-steps. - Keep the old code working until the new code is verified. Don't delete the old
pages/directory untilapp/is fully functional. - Use the Impact Analysis technique before starting if you're unsure about the blast radius of the migration.