Plan a Major Dependency Upgrade
Read the migration guide, isolate the upgrade in a branch, run codemods and compatibility tests, canary the change, and keep a tested rollback.
Objective
Move to a new major version without silently changing behavior or discovering breakage in production.
Environment
- A lockfile and a reproducible build
- A test suite with integration coverage
- A canary or staging environment
- The dependency's changelog and migration guide
Steps
1. Read the breaking changes
List removed APIs, changed defaults, runtime requirements, and peer dependency changes. Map each to code or configuration that uses it.
Expected state: Every breaking change has an owner and a planned migration.
2. Upgrade in isolation
Create a branch, update the dependency and its peers, and run codemods or manual replacements.
Expected state: The dependency tree resolves and the build compiles.
3. Run compatibility tests
Run unit, integration, and contract tests, plus targeted tests for the changed behavior.
Expected state: Failures are explained by known breaking changes, not by unrelated flakiness.
4. Canary the change
Deploy to staging or a small production cohort and compare error rate, latency, and key business metrics with the baseline.
Expected state: The new version meets the same gates as the old one.
5. Roll out or roll back
Expand the rollout when gates pass; roll back to the previous lockfile if a regression appears.
Expected state: The upgrade is reversible and the rollback is tested.
Decision points
Should all major dependencies be upgraded together?
- One major upgrade at a time
- Batch related packages
Upgrade one major dependency at a time unless the ecosystem requires a coordinated set; isolate failures.
What if the migration guide is incomplete?
- Read the changelog and source diffs
- Wait for a community guide
Inspect the source and tests for the changed behavior; do not guess from release notes alone.
Expected outcome
The dependency is upgraded with no unplanned behavior change, and the team has evidence that the new version works in production.
Verification
Compare the lockfile, run the full suite, and check canary metrics against the baseline. Confirm the application starts with the new runtime and peer dependencies.
Cleanup
Remove compatibility shims and deprecated API usage, update documentation, and record the version and migration notes.
Read before upgrading
A major version exists because something changed incompatibly. Read the migration guide and changelog, list the removed APIs and changed defaults, and search the codebase for each. An upgrade that starts with pnpm update and a failing test run wastes time rediscovering the documented changes.
pnpm outdated
pnpm add dependency@next-major
pnpm test
Isolate the change
Upgrade one major dependency at a time. If several packages must move together, treat the set as one change with a shared rollback. Keep the lockfile diff reviewable. Run codemods where available, but inspect their output; a codemod that compiles can still change behavior.
Test behavior, not only compilation
Compilation proves the API exists, not that it behaves the same. Run integration and contract tests, and add targeted tests for changed defaults, error handling, and serialization. Canary the change and compare metrics with the baseline. If a regression appears, roll back the lockfile first, then investigate on a branch.