Yes, a library can commit its lockfile, and for most projects it should, because it makes your own CI and releases repeatable. But the lockfile does not travel to your users. They resolve versions from your manifest ranges, so you still need to test against newer dependencies.
What a lockfile does for you
A lockfile records the exact dependency tree that was resolved on a given day. The npm documentation describes package-lock.json as describing "the exact tree that was generated," so later installs produce the same tree, and it is meant to be committed so teammates, deployments and CI install the same dependencies.
For a maintainer that means a failing build points at your change, not at a dependency that quietly released overnight. It also means a security fix to a dependency shows up as a visible diff in a pull request, which is easy to review.
What a lockfile does not do for your users
The same npm page says the file "cannot be published, and it will be ignored if found in any place other than the root project." A person who installs your package never receives your lockfile. Their package manager reads your declared ranges and picks versions on their own.
Cargo's FAQ makes the same point for Rust: the determinism of a lockfile "can give a false sense of security because Cargo.lock does not affect the consumers of your package, only Cargo.toml does that." The Cargo docs also say whether you track the file depends on the needs of your package.
This matters for security. If your lockfile pins a patched version of a dependency but your manifest range still allows the vulnerable one, your users can still end up with the vulnerable one.
A practical setup
| Question | Answer |
|---|---|
| Commit the lockfile? | Yes, for repeatable CI and reviewable updates |
| Does it protect users? | No, only your manifest ranges do |
| Where do the minimum safe versions go? | In the manifest, as the lower bound |
| How do you catch breakage from new releases? | A separate CI job that resolves the latest versions |
Steps:
- Commit the lockfile and use a frozen install in CI. For npm,
npm ciinstalls exactly what the lockfile says and exits with an error if it does not matchpackage.json, instead of updating it. - When an advisory affects a dependency, raise the lower bound in the manifest to the patched version, not just the lockfile entry.
- Add a second CI job that ignores the lockfile and resolves the newest allowed versions. Run it on a schedule or on pull requests, and allow it to fail without blocking merges, so you learn early without stalling contributors.
Cargo documents this pattern directly: run cargo update, then build and test, in a job marked to continue on failure.
When not committing one is fine
Some small libraries with few dependencies skip the lockfile so that every CI run exercises the latest allowed versions. The Cargo guide lists this as an option, with the trade-off that many versions go untested and builds lose determinism. If you choose this, make sure CI still runs often enough to notice breakage.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how direct and transitive dependencies appear separately, which is the tree your lockfile freezes.
Quick check
Does my lockfile protect people who install my package?
No. Consumers get your package and resolve dependencies from your declared ranges. Only the manifest affects them.
Is it wrong for a library to skip the lockfile?
Not wrong, but you trade repeatable builds for exposure to the newest versions. Make sure CI runs often so breakage surfaces quickly.
If you want an inventory of what your project resolves today, including transitive packages, the free scan from Safeguard reads your dependencies and reports known vulnerabilities.
Sources
- npm docs, package-lock.json: https://docs.npmjs.com/cli/v10/configuring-npm/package-lock-json
- npm docs, npm ci: https://docs.npmjs.com/cli/v10/commands/npm-ci
- Cargo FAQ: https://doc.rust-lang.org/cargo/faq.html
- Cargo guide, continuous integration: https://doc.rust-lang.org/cargo/guide/continuous-integration.html
Last reviewed: 19 October 2026.