Go one major at a time unless the release notes say a direct jump is supported. Each major can remove what the previous one deprecated, and stepping lets you fix warnings in small batches and find which release broke what. A single big jump is faster only when nothing breaks.
Why stepwise usually wins
SemVer says a major version marks backward incompatible changes to the public API, and that deprecated functionality should live for at least one minor release before it is removed in a major. The Keep a Changelog guidance describes the same path from the user's side: it should be possible to upgrade to a version that lists deprecations, remove what is deprecated, then upgrade to the version where the deprecations become removals.
That is the stepwise plan in one sentence. Following it turns an opaque jump across three majors into a series of small, testable moves.
When a direct jump is acceptable
| Condition | Direct jump? |
|---|---|
| The maintainers publish a guide for jumping | Yes, follow it |
| Small API surface, thorough tests | Possibly |
| Heavy use of removed or changed features | No, go stepwise |
| Data formats or stored state change between majors | No, migrate one step at a time |
| Urgent advisory and a backport is available | Take the backport, schedule the upgrade |
The plan
- Read the changelogs from your current version to the target. List every Deprecated and Removed entry that touches your usage.
- Move to the last minor of your current major. This is where deprecation warnings usually appear.
- Fix every deprecation warning on that version, and release it. You are now safer to upgrade.
- Upgrade to the next major. Run the tests, fix breaks, run a smoke test, and release.
- Repeat until you reach the fixed version.
- Rescan after each step. The vulnerable version may already be gone at an earlier step.
Step 6 is easy to miss. A fix is sometimes backported to an intermediate major, so you may be able to stop early.
Make each step reversible
Commit each step separately with the lock file. If step 4 breaks production, you roll back one step, not the whole project. The guide on rolling back a bad dependency upgrade merge covers the mechanics.
If the upgrade is too big for the time you have, mitigate in the meantime. Options include a backported fix, a configuration change that disables the vulnerable feature, or a compensating control. Record the exception with an owner and a review date.
Add tests before step 2
Write characterization tests for how your code uses the library, so the same tests run before and after each step. This is the highest return investment in a multi step upgrade. The decision on whether to move at all is covered in should I upgrade a major version dependency.
Try it yourself
Click through it at your own pace, or open it full screen. Check which release first contains the fix, since that sets how far you must go.
Where Safeguard fits
Safeguard scans dependencies, runs reachability analysis to show which findings your code can actually reach, and can open fix pull requests through autonomous remediation. That last feature is off by default and every category starts on Manual, so a person approves each change. You can try a free scan on a repository first.
Quick check
Why upgrade to the last minor of the current major first?
Deprecations are usually announced in minor releases, so that version warns you about what the next major removes.
Can I stop before the newest major?
Yes, if an intermediate release already contains the fix. Rescan after each step to see.
Sources
Last reviewed: 19 October 2026.