npm update only moves a package to the newest version that your declared range allows. If the fixed release sits outside that range, nothing changes. By default it also leaves the range in package.json untouched. To reach the fix, change the range, use the save option, or install the fixed version by name.
What npm update promises
The npm documentation says the command updates the listed packages to the latest version, respecting the semver constraints of both your package and its dependencies when they also require the same package. If you do not name a package, everything in the location is updated.
Two details explain most surprises. First, by default npm update does not update the semver values of direct dependencies in package.json. The docs say you can add the save option if you also want those values updated. Second, the range type changes how far it can go.
Why a range blocks the fix
The docs walk through examples. A caret range on a 1.x package allows newer minor and patch versions of that major series, and a tilde range allows only patch changes. Caret ranges below 1.0.0 are tighter: a caret on 0.2.0 stays within the 0.2 series, and a caret on 0.4.0 moves only within the 0.4 series, so a 0.3 release is out of reach.
| Declared range | Fixed release | Does npm update reach it? |
|---|---|---|
| Caret 1.1.0 | 1.1.5 | Yes |
| Tilde 1.1.0 | 1.2.0 | No, minor change |
| Caret 1.1.0 | 2.0.0 | No, new major |
| Caret 0.2.0 | 0.3.0 | No, 0.x is tighter |
The lock file also matters. If the fixed version satisfies the range but your lock file records an older version, the update command is what refreshes it, and a plain install keeps the locked version.
Steps to move it
- Check the advisory for the first fixed version.
- Compare it to your declared range for the package.
- If it fits, run the update for that package only, then review the lock file diff.
- If it does not fit, install the fixed version by name so the manifest range changes with it.
- If the package is transitive, find the parent that sets its range. Updating the parent may be enough, otherwise an override applies (see npm overrides).
- Run your tests and rescan.
npm update somepackage
npm install somepackage@2.0.1
A note on majors
Moving to a new major version is not an update, it is an upgrade with a migration cost. Read the changelog first, and see the guide on whether to upgrade a major version dependency.
Verify
After the command, list the package and confirm the version at every path. A fix that applied to one path and not another is common when two parents require different ranges. The lock file diff is the record of what actually changed, so read it.
Try it yourself
Click through it at your own pace, or open it full screen. Compare a fixed version with the range you have today.
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
Does npm update edit package.json?
Not by default. The docs say you need the save option to update the declared ranges.
Why does a caret range on 0.x move so little?
For versions below 1.0.0, the caret allows only changes within the same minor series, so it is tighter than on 1.x and above.
Sources
Last reviewed: 19 October 2026.