If your team has gone a year without updating dependencies, do not start with the biggest upgrade. Spend week one on inventory, week two on urgent fixes, week three on patch and minor batches, and week four on the first planned major plus a standing routine. Four weeks is enough to change direction, not to finish.
Week 1: see what you have
Build a complete inventory of direct and transitive dependencies with versions, per repository. Add the runtime versions. For each runtime, note its published support end date: Python and Node.js both publish status for each release.
Also name an owner for every repository. Without owners, the plan stalls in week two.
Output: one table of repositories, oldest runtime, number of majors behind on core frameworks, and owner.
Week 2: fix what matters most
Match the inventory against known exploited vulnerabilities, using CISA's catalog as an input to prioritization. Then run reachability on the remaining findings to see which affect code you actually call. Mark internet facing services.
Fix the top group now, taking the smallest change that includes the fix. Record anything you cannot fix, with a compensating control and a date.
Output: urgent list closed or excepted with dates.
Week 3: batch patches and minors
Semantic versioning says patch and minor releases should be backward compatible, so they are the cheapest wins. Update them in small groups, a few packages at a time, so a failure points to a short list. Merge behind passing tests.
Turn on automated pull requests for outdated dependencies so the small updates keep coming. GitHub documents this style of version update as running even when dependencies have no vulnerabilities.
Output: patches and minors current, automation on.
Week 4: first major and the routine
Pick one major upgrade, starting with whatever is closest to end of life or most exposed. Read the changelog, list breaking changes, and upgrade in a branch with its own test plan. Do not start a second major until the first is merged.
Then set the standing routine: weekly review of update pull requests, monthly check of exploited and reachable findings, quarterly major.
Output: one major in flight or done, calendar entries made.
Plan summary
| Week | Focus | Result |
|---|---|---|
| 1 | Inventory and owners | One table |
| 2 | Exploited and reachable fixes | Urgent list closed |
| 3 | Patch and minor batches | Automation on |
| 4 | First major and routine | Cadence set |
Risks to manage
- Updating everything at once, which hides the cause of failures.
- Skipping tests because the list is long.
- Declaring victory after week four. The routine matters more than the sprint.
Safeguard's SBOM and dependency scanning lists direct and transitive packages with their versions, and reachability analysis shows which outdated or vulnerable ones your code actually calls. Autonomous remediation can open fix pull requests; it is off by default and every category starts on Manual. You can try a free scan at gold.safeguard.sh/scan.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how ongoing monitoring flags new findings so the backlog does not rebuild.
Quick check
What if we only have one engineer for this?
Do weeks one and two fully, then let automation handle patches while you take one major per quarter.
Do we need a freeze on features?
Usually not. A protected slice of each sprint works better than a freeze, which tends to overrun.
Sources
- CISA Known Exploited Vulnerabilities Catalog
- Semantic Versioning 2.0.0
- About version updates, GitHub Docs
- Status of Python versions
- Node.js releases
Last reviewed: 19 October 2026.