Safeguard
Developer Tools•

Which lockfile does each language use, and should you commit it?

Lockfile names and commit guidance for npm, Cargo, Composer, NuGet, Gradle, pip and Go, with a rule of thumb for applications versus libraries.

Safeguard Security Team
4 min read

Commit the lockfile for anything you deploy: applications, services and tools. For a library that others depend on, the lockfile mostly does not affect your consumers, so opinions differ, and some ecosystems say not to commit it. Names vary: package-lock.json, Cargo.lock, composer.lock, packages.lock.json, gradle.lockfile, go.sum and pylock.toml.

What each ecosystem calls it

EcosystemLock or checksum fileNotes from the docs
npmpackage-lock.jsonClean install requires it
Rust (Cargo)Cargo.lockCreated by default for new projects
PHP (Composer)composer.lockDocs advise committing it for projects
.NET (NuGet)packages.lock.jsonOpt in with a project property
Gradlegradle.lockfileOpt in per configuration
Gogo.sumRecords checksums, alongside go.mod
Pythonpylock.tomlStandard format from PEP 751

Two caveats. Go is different in kind: go.mod already states exact minimum versions, and go.sum holds hashes used to verify downloads. Python has several tool specific lock formats, and PEP 751 defines a shared one, which the PEP status page lists as final.

Applications: commit it

The reasons are the same everywhere. A committed lock gives you the same dependencies on every machine and on every day. The Cargo FAQ lists the benefits: deterministic builds, easier bisecting, and CI failures that trace to a commit instead of to a new upstream release. Composer's docs say to commit the lock so CI servers, production machines and teammates all use the same versions.

Libraries: it depends, and the docs differ

The Cargo FAQ notes the lockfile does not affect consumers of your package, since only the manifest does that. Composer's docs say libraries do not need to commit it. NuGet's docs go further and say a library project you do not ship should not check in the lock file, because the consuming application's own resolution decides what is installed.

You may still want a lock in a library repo for your own CI. The Cargo FAQ lists that as a reason to commit. Just do not assume it protects the people who install your library.

Opting in where the lock is not automatic

For NuGet, set the restore property for a lock file, and the project then writes packages.lock.json. For Gradle, call the dependency locking setup, then write the initial lock state with the dependencies task and its write-locks option, and commit gradle.lockfile at each project root.

What to check in review

  1. Is the lockfile present in the repo?
  2. Did the manifest change without a matching lock change?
  3. Does the lock diff show only the packages you expected?

That last check is the human one. A pull request that bumps one dependency should not rewrite two hundred lines of unrelated versions without an explanation.

Safeguard can help here: it scans dependencies and generates SBOMs, applies reachability analysis so you can sort findings by what your code can actually call, and enforces policies and gates on pull requests. You can try a free scan on a repository to see what it finds.

Quick check

Does committing a lockfile protect people who install my library?

Generally no. For Cargo, the FAQ says the lockfile does not affect consumers of your package, only the manifest does.

Is go.sum a lockfile?

Not exactly. It stores checksums that Go uses to verify downloaded modules. Version selection is recorded in go.mod.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.