Across ecosystems the answer is similar: write honest ranges in the manifest, commit a lock file for anything you deploy, and install from the lock in CI. What differs is the file name, the install command that respects it, and what a plain version number means. This guide puts them side by side.
The pattern
A manifest says what you accept. A lock file says what you got. Applications need the second. Libraries need the first, since consumers resolve from your manifest and not from your lock file. The Cargo Book and Composer's documentation both say so for their ecosystems.
The comparison
| Ecosystem | Lock file | CI install that respects it | A plain version means |
|---|---|---|---|
| npm | package-lock.json | npm ci, which errors on mismatch | A full version such as 1.0.4 is exact, a partial one such as 1.0 is a range |
| Python with Poetry or uv | poetry.lock, uv.lock | The tool's sync or install command | Depends on the tool and field |
| Python with pip | Pinned, hashed requirements file | Install with required hashes | Exact only with double equals |
| Rust | Cargo.lock | Locked option on cargo install, check your Cargo version for other commands | Caret range |
| Go | go.sum with go.mod | Standard build, plus go mod verify | A minimum version, selected minimally |
| Maven | Exact versions in the POM, managed in one place | Build with those exact versions | A soft requirement |
| Gradle | gradle.lockfile when enabled | Build with locking active | Exact unless it uses a dynamic form such as 1.+ |
| NuGet | packages.lock.json when enabled | Restore in locked mode | A minimum version |
| Composer | composer.lock | composer install | An exact version |
| Terraform | .terraform.lock.hcl | Init with the lock committed | Exact match |
Each row comes from that ecosystem's own documentation, linked below. Where the table says depends or where supported, check the page for your version.
Notes that save time
- The npm documentation lists a plain, partial version as a range: 1.0 or 1.0.x is a patch range, and 1 or 1.x is a minor range.
- In Cargo, leaving off the caret is exactly equivalent to a caret requirement.
- In NuGet, a plain 6.1 is a lower bound. Square brackets pin exactly.
- In Maven, a plain 1.0 is soft and can be replaced by another version elsewhere in the tree.
- In Go, minimal version selection means a requirement is a floor and the build picks the lowest set that works.
Choosing, in four questions
- Do you deploy this code? If yes, commit the lock file and install from it.
- Do others install this code? If yes, publish honest, tested ranges and no star requirements.
- Can the ecosystem tell you when the lock and manifest disagree? Turn that on in CI.
- Who reviews lock diffs? Name them. A lock change is a dependency change.
What none of this covers
Locks and pins fix versions. They do not make a version safe, and they do not stop a dependency from being compromised before you first lock it. You still need scanning, review of new direct dependencies and a way to move quickly when an advisory lands.
Where Safeguard fits
Safeguard's dependency scanning and SBOM generation work from what your projects actually resolve, whichever package manager produced it, and policies and gates can enforce your rules in review. A free scan is at gold.safeguard.sh/scan.
Try it yourself
Open the inventory and notice that the same view of resolved packages applies whatever package manager produced the list.
Click through it at your own pace, or open it full screen.
Quick check
Do I need a lock file for a library?
Not for your consumers. They resolve from your manifest. A lock file can still help your own CI and tests.
Is there one rule that works everywhere?
Commit a lock file for what you deploy, install from it in CI, and review every diff to it.
Sources
- npm Docs: About semantic versioning
- pip documentation: Secure installs
- The Cargo Book: FAQ
- Go Modules Reference
- Apache Maven: POM Reference
- Gradle: Dependency locking
- Microsoft Learn: Package versioning
- Composer: Basic usage
- Terraform: Dependency lock file
Last reviewed: 19 October 2026.