Lockfiles and reproducible builds: The same versions everywhere
In short: A lockfile records the exact installed versions of all packages so that development, CI and production use the same state and builds remain reproducible.
In more detail: In package.json it says "express": "^4.18.0", meaning “4.18.0 or newer 4.x”. Without further measures every machine installs different versions depending on the time: “it works on mine” becomes a problem. The lockfile solves that.
In Depth
What is in it?
A lockfile contains all direct and transitive dependencies with exact version, checksum (hash) and origin. Examples: package-lock.json (npm), pnpm-lock.yaml, yarn.lock, Cargo.lock (Rust), poetry.lock/uv.lock (Python), Gemfile.lock, composer.lock, go.sum. It is generated by the tool, not edited by hand.
Using it correctly
- Commit the lockfile to the repository (for applications; for libraries depending on convention, sensible for CI).
- In CI and deployment install with the lockfile:
npm ci(instead ofnpm install),pip install -r requirements.txt --require-hashes,cargo build --locked.npm ciaborts if lockfile andpackage.jsondo not match. - Run updates deliberately (
npm update, Dependabot/Renovate), review changes in the lockfile in the pull request. - Merge conflicts in the lockfile: do not merge by hand; resolve
package.jsonand let the lockfile be regenerated.
Reproducible builds
Goal: same inputs → same result (bit for bit). For this: lockfiles, pinned tool versions (.nvmrc, .tool-versions, engines), containers with fixed base images (digest instead of latest), no timestamps in the build, deterministic ordering. This eases troubleshooting, rollbacks, security checks (SBOM, signatures) and the confidence that a published artifact matches the source code.
Security
Lockfiles with hashes protect against a package being swapped afterwards. Check manipulated lockfiles in pull requests (different registry URL). Use private registries/proxies (Artifactory, Verdaccio) for control. You avoid dependency confusion with clear namespaces (scopes) and registry configuration.
See also: Semantic versioning, Dependabot and Renovate, Dependencies and libraries