Two failure modes bracket this problem. Pin every dependency to an exact version and never update, and you end up years behind with known vulnerabilities and an upgrade path that has become a rewrite. Use loose version ranges with no lockfile, and your build resolves differently on Tuesday than it did on Monday, with no change to your code.
The workable position is pinned resolution with an active refresh process.
What changed in 2026
- Update automation became standard. Bots opening pull requests for dependency updates moved from a nice-to-have to a baseline expectation in maintained projects.
- Grouping got emphasized. Batching related updates into single pull requests replaced the per-dependency flood that teams learned to ignore.
- Transitive visibility improved. Tooling surfaced what indirect dependencies actually changed in an update, rather than only the direct one.
- Supply chain scrutiny tightened. Compromised packages and typosquatting incidents pushed teams toward reviewing what an update actually changes rather than merging on green tests alone.
Lockfiles versus ranges
|
Manifest range |
Lockfile |
| Expresses |
What versions are acceptable |
What versions were resolved |
| Purpose |
Upgradability and compatibility |
Reproducibility |
| Covers transitive dependencies |
No |
Yes |
| Commit for applications |
Yes |
Yes |
| Commit for libraries |
Yes |
Usually not |
| Changes when |
You decide |
Resolution runs |
The two do different jobs and both belong in the repository for an application. The manifest declares your intent about compatibility; the lockfile records what that intent resolved to, including every transitive dependency, so a build today matches a build last week.
Libraries are the exception. A library committing a lockfile pins nothing for its consumers, since they resolve against their own tree, and it can mislead maintainers into testing against versions users will not have.
Making the refresh work
Pinning is only safe if something regularly unpins. Automated update pull requests are that mechanism, and how you configure them determines whether they get reviewed or ignored.
Group them. One pull request per dependency produces a stream nobody reads. Group by ecosystem, by update type, or by related packages, so a weekly batch is one reviewable change rather than fifteen.
Schedule rather than stream. A predictable weekly batch fits into a work rhythm; continuous notifications do not.
Auto-merge conservatively. Patch and minor updates with a passing test suite are reasonable to merge automatically. Major versions carry breaking changes by definition and need a human. Security updates deserve their own faster path.
Read what changed for anything unusual. A dependency you have never heard of appearing in a transitive update, or a package changing maintainers, is worth a look. This is where supply chain compromise enters, and green tests do not detect a package that behaves normally while exfiltrating.
Keep the test suite meaningful. Auto-merge is only as safe as what it gates on. A suite that does not exercise the dependency provides no signal.
Common mistakes
- Pinning with no update process. Becomes rot with known vulnerabilities.
- No lockfile. Builds resolve differently over time for no visible reason.
- Committing a lockfile in a library. Pins nothing for consumers, misleads maintainers.
- Per-dependency pull requests. Volume ensures nobody reviews them.
- Auto-merging majors. Breaking changes are the definition of the version bump.
- Never reading update contents. The supply chain attack looks like an ordinary bump.
FAQ
Should I pin exact versions in the manifest?
Generally no. Use ranges in the manifest and let the lockfile pin resolution. Exact manifest pins make transitive resolution harder for everyone.
How often should I update?
Weekly batches for routine updates, immediately for security advisories. Longer intervals let upgrade debt accumulate into a project.
What about a dependency that has not been updated in years?
Sometimes that means stable and finished, sometimes abandoned. Check maintenance activity and open issues rather than assuming either.
Does pinning give me reproducible builds?
It is necessary and not sufficient — the toolchain and environment matter too, per hermetic builds explained.
Where to go next
For the automation tools, read Renovate vs Dependabot. For inventory, SBOM and supply chain security, and for build guarantees, reproducible builds guide.