Anchoring your dependencies in choppy supply-chain seas
In the rich tapestry of modern software supply chains, your
package-lock.json is, frankly, the only thing keeping your
production deployment from drifting into a reef. Let's unpack this.
What is an anchor, really?
An anchor is a heavy thing that prevents a lighter thing from going
somewhere it shouldn't. A lockfile is, in this and only this respect,
identical: it is a heavy file that prevents your dependency tree from
going somewhere it shouldn't — namely, "whatever npm felt like
installing this Tuesday."
Why pin?
Without pinned versions, every npm install on a fresh machine
is an act of cautious optimism. The same is true of dropping anchor without
a chain log: you may indeed be holding fast, or you may be slowly, silently
dragging across the bay while you sleep. Both situations end the same way:
with someone, somewhere, calling at 3am.
- Reproducibility — you and CI install the same thing.
- Auditability — when something breaks, you can ask "what changed," and the answer is not "the wind."
- Security — fewer surprise transitive updates means fewer surprise compromised packages.
What about updates?
You do, occasionally, have to weigh anchor and move. The same is true of
dependencies — you cannot stay on left-pad@1.1.0 forever, no
matter how peaceful the bay is. The trick is doing it deliberately:
- Update one ecosystem at a time. Don't bump npm, pip, and Cargo in the same PR. That's not a sailing trip — that's a shipwreck.
- Read the release notes. Yes, all of them. This is the boring part of both software and sailing.
- Run the tests. If the tests pass on a Tuesday, the seas are calm. Ship it. (Allegedly. The AI is not your CI.)
Supply-chain attacks, or: pirates
A compromised upstream package is a pirate. Your lockfile is the
cannon. Your CI is the lookout. Your incident response plan is whoever on
the team last successfully ran git revert without panicking.
Build all three. Drill all three. Pretend the pirates are real, because
they are, in fact, real.
An overextended conclusion
Pin your versions. Audit your tree. Update on purpose. And when something does go wrong — because eventually it will — remember that the difference between a sinking ship and a controlled retreat is mostly just how prepared you were before things got interesting.
For the manifesto that started this — and for which the author offers no defense — see Regatta-Driven Development.