Give every override, pin and patch an owner, a reason and a review date at the time you add it, and check them on a schedule. An override is a promise to remove it once upstream catches up. Without a date, nobody keeps the promise and the file collects stale workarounds.
Why overrides rot
Overrides fix a real problem quickly, which is why they get added during incidents. The npm documentation describes them as a way to replace a version with a known security issue, or replace a dependency with a fork, or make sure the same version of a package is used everywhere. That power is also the risk: the override tells the tool to ignore what a parent asked for. Once the parent releases a version that requires the fixed child, the override is redundant. If the parent later changes in ways your override does not expect, it can even do harm.
Some features of overrides add to the problem. The npm docs state that overrides are considered only in the root package.json, not in installed dependencies. So the override is yours alone, and nobody upstream knows about it.
What to record
| Field | Example content |
|---|---|
| Package and version forced | Name and the fixed version |
| Reason | Advisory identifier and a one line summary |
| Parent that blocks the fix | The package whose range prevented a normal bump |
| Owner | A named person or team |
| Added on | The date |
| Review by | A date within three months |
| Exit condition | The parent version that makes it unnecessary |
Keep the record next to the code, as a comment beside the override and a row in your exception register. Gradle supports a reason string on constraints, and similar notes work in any manifest that allows comments or sidecar files.
A review routine
- Monthly, list every override, pin and patch file in the repositories.
- For each, check whether the parent now allows the fixed version. If yes, remove the override and run the install.
- Compare the lock file before and after. If nothing changed, the override was redundant. If something changed, review it.
- Run the tests and rescan.
- For items still needed, extend the review date and note why.
- For items older than a set limit, escalate: replace, fork, or accept the risk formally.
grep -rn "overrides\|resolutions\|patchedDependencies" --include=package.json --include=pnpm-workspace.yaml .
Automate what you can
A CI check can fail when an override has passed its review date, or open an issue assigned to the owner. A scanner can flag when an override forces a version that has since been marked vulnerable itself. Pinned fixed versions can age into new advisories too, so a pin is not a one time decision.
Related practices
Treat patch files and forks the same way, since they carry the heaviest upkeep. See the guides on pnpm and Yarn patches and yarn resolutions. If you manage exceptions centrally, the register should link back to these entries.
Try it yourself
Click through it at your own pace, or open it full screen. See how ongoing monitoring catches changes after a fix, which is the same idea as reviewing overrides on a schedule.
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
How long should an override live?
Only until the parent allows the fixed version. Set a review date of about three months and renew it only with a reason.
Can a library publish overrides to protect its users?
Not through npm overrides. The docs say only the root project's overrides apply, so users must set their own.
Sources
Last reviewed: 19 October 2026.