For applications, a fix pull request should change the resolved version in the lockfile to the fixed release, and keep the manifest range only if it already allows that version. For libraries, widen or raise the minimum so consumers cannot resolve a vulnerable version. Pin exactly when repeatability matters more than automatic patches.
What the options mean
In npm, a bare version such as 2.0.1 must match exactly. A caret range means compatible with that version, and a tilde means approximately equivalent, as the npm package.json documentation describes. Wildcards, comparison operators and unions also exist.
Go works differently. Its modules use minimal version selection: required versions are minimums, the build list is deterministic, and a new release does not change your build unless something in your graph requires it. A go get with a version updates the requirement in go.mod.
Containers add a third model. Docker's guidance says tags are mutable, and that pinning to a digest guarantees the same image, with the tradeoff that pinning opts you out of automatic security fixes unless something updates the pin.
Decision table
| Project type | Manifest | Fix PR should |
|---|---|---|
| Application, npm | Range plus lockfile | Update the lockfile, leave the range if it allows the fix |
| Library, npm | Range, no lockfile for consumers | Raise the lower bound to the fixed version |
| Go module | Minimum versions | Raise the required version in go.mod |
| Container image | Tag or digest | Update the tag and digest together |
Why pinning is not a security measure by itself
Exact pins make builds repeatable and slow the arrival of a compromised release. They also freeze known vulnerabilities in place. A pinned dependency with no update process drifts toward being the vulnerable one. Pair pinning with a steady stream of reviewed updates, which is the job of fix pull requests.
A lockfile only change
Many fixes touch only the lockfile. They are small, but they can move transitive packages too. Read the diff for added and removed entries. The post on lockfile only fix versus manifest change explains what to check.
When to hold the range
If a range allows a vulnerable version and your lockfile is regenerated often, a fresh install could pull it again. Raise the lower bound in the manifest for libraries, so the guarantee does not depend on a lockfile.
Where Safeguard fits
Safeguard's SBOM and dependency scanning shows the exact resolved versions of what you ship, and autonomous remediation opens fix pull requests with every category on Manual by default. Try a free scan.
Try it yourself
Click through it at your own pace, or open it full screen. Look for the difference between a declared range and the version actually resolved.
Quick check
Does pinning make me safer?
It makes builds repeatable. Safety needs a process that updates pins when fixes appear.
Where do ranges still make sense?
In libraries, where consumers choose the final version and you should declare the lowest safe one.
Sources
Last reviewed: 19 October 2026.