Commit the lockfile for any application you build and deploy, because it makes every machine and every CI run resolve the same dependency tree. For a library, the answer depends on the ecosystem: the file helps your own tests but does not change what your consumers install.
Why applications should commit it
A manifest says what you will accept. A lockfile says what you got. The npm documentation says package-lock.json is meant to live in the source repository so teammates, deployments and CI install the same versions, and so changes to the tree show up in source control diffs.
The Cargo documentation gives practical reasons that apply anywhere: bisecting a bug, making sure CI fails only because of new commits and not external changes, and avoiding contributors seeing different behaviour from each other.
What the docs say per ecosystem
npm. Commit package-lock.json. The file records version, resolved location and an integrity hash for each package.
uv for Python. The uv documentation says uv.lock should be checked into version control, which keeps installs consistent across machines and fixes the package set for an application deployment.
NuGet. If you are building an application, check in packages.lock.json. For a library you do not ship, or common code that other projects depend on, Microsoft says you should not check it in, because the locked versions cannot be used when a dependent project restores. The consumer's own resolution wins.
Cargo. The Cargo FAQ says tracking Cargo.lock depends on the needs of your package, and that cargo new tracks it by default. It warns that the file does not affect consumers of your package, which can give a false sense of security.
Gradle. The Gradle documentation says to commit gradle.lockfile.
Libraries are the tricky case
When someone installs your library, their package manager resolves your dependency ranges alongside everything else. Your lockfile is not consulted. So a library lockfile does not protect your users.
It still has value for you. It gives your tests a stable baseline, and CI failures then point at your code. The Cargo documentation also suggests separately verifying against the latest dependency versions, since your users will not be on your locked ones.
A simple rule set
- Application or service: commit the lockfile, and install from it in CI with a command that fails on drift.
- Library: decide per ecosystem, and test against fresh resolution as well as locked.
- Any project: never commit hand edits to a lockfile. Let the tool write it.
Where scanning fits
A lockfile is also the most accurate input for a dependency inventory. Safeguard's SBOM and dependency scanning works from your dependency data, and you can run a free scan at gold.safeguard.sh/scan. For a Rust specific view, see should you commit Cargo.lock for a library.
Quick check
Does my library's lockfile protect people who install it?
No. Consumers resolve from your published dependency ranges, not from your lockfile.
Is it bad to commit a lockfile in a library?
Usually not harmful, but check your ecosystem. NuGet advises against it for libraries you do not ship.
Sources
- package-lock.json, npm Docs
- Cargo FAQ, The Cargo Book
- Project layout and uv.lock, uv documentation
- PackageReference in project files, Microsoft Learn
- Dependency locking, Gradle User Manual
Last reviewed: 19 October 2026.