To pin dependencies, commit your lockfile, install from it in CI with a command that refuses to change it, such as npm ci, and use hash checking where your ecosystem supports it. Then review lockfile diffs like code, because a pin only helps if the pinned thing is the thing you intended.
Key takeaways
- A manifest says what you accept. A lockfile says exactly what you got.
- npm ci fails when the lockfile and package.json disagree, instead of quietly updating.
- pip hash-checking needs exact versions and hashes for every dependency.
- Pinning stops surprise upgrades. It does not make a bad version good, so keep scanning.
- Pin build tools and CI actions too.
What is the difference between pinning and a lockfile?
Pinning fixes one version in the manifest, while a lockfile records the full resolved tree, including transitive dependencies. You want the lockfile, since most of what you run is not listed in your manifest.
How do I install from the lockfile in CI?
Use npm ci. According to the npm documentation, it needs an existing package-lock.json or npm-shrinkwrap.json, exits with an error if they disagree with package.json, and never writes to package.json or any lockfile.
npm ci
Know its side effects. It deletes an existing node_modules before installing, it cannot add individual packages, and if the lockfile was created with install flags such as legacy peer deps or install links, you must pass the same flags to npm ci.
How do I pin Python dependencies?
Use exact versions and hashes. pip's hash-checking mode verifies downloads against hashes in your requirements file. Every requirement must use ==, a URL or a path, and all requirements and their dependencies need hashes, or the install fails. sha256 is the recommended algorithm.
pip install --require-hashes -r requirements.txt
List several hash entries for a package that has wheels for multiple platforms or both wheel and source distributions.
What should I check when a lockfile changes?
Look at the diff for three things: packages you did not ask for, version jumps beyond what the manifest change implies, and resolved URLs that point somewhere unexpected. Require code owner review on lockfiles so nobody merges a regenerated file unread.
Do pins protect me from a compromised release?
Only until you update. A pin keeps you on the version you tested, which blocks a surprise malicious release, but an already pinned bad version stays. Scan the lockfile regularly. The free Safeguard dependency scan accepts package.json, requirements.txt and SBOMs, runs in your browser with no login, and covers up to 100 dependencies.
Frequently asked questions
Should I commit the lockfile?
Yes for applications. It is what makes installs repeatable across machines and CI.
Why does npm ci fail on my pipeline?
The lockfile and package.json disagree, or the lockfile is missing. Regenerate it locally with npm install and commit it.
Do hashes replace version pins in pip?
No. pip requires exact versions as well, which prevents a surprising hash mismatch when a new release matches a loose specifier.
Do GitHub Actions need pinning too?
Yes. Pin them to full-length commit SHAs, as GitHub recommends. See how to secure GitHub Actions.
Sources
Last reviewed: 19 October 2026.