Skip to main content
Category: Software Supply Chain

Lockfiles

Also known as: lock files, dependency lock files, package lock files
Simply put

A lockfile is a file that records the exact, pinned versions of every dependency (including transitive dependencies) required by a software project, ensuring that the same versions are installed consistently across different environments. In package management contexts, lockfiles prevent unexpected version changes when dependencies are installed. They are a key control for reproducible builds and supply chain integrity.

Formal definition

In package management and build systems, a lockfile is a metadata artifact that enumerates specific pinned versions of all direct and transitive third-party dependencies resolved at a point in time. By capturing the full resolved dependency graph with exact version identifiers (and typically integrity hashes), a lockfile enables deterministic installation, meaning that any subsequent install operation reproduces the same dependency set regardless of upstream registry changes or new releases. Committing lockfiles to source control is a recommended practice because it makes the resolved dependency graph auditable and reviewable. Lockfiles are distinct from manifest files (such as package.json or requirements.txt), which typically specify version ranges rather than exact resolved versions. Note that a lockfile records versions resolved at generation time; it does not by itself detect or prevent the introduction of malicious packages, and it does not guarantee integrity unless the tool also validates cryptographic hashes at install time.

Why it matters

Lockfiles are a foundational control for reproducible builds and software supply chain integrity. Without a lockfile, each fresh installation of a project's dependencies resolves versions according to the ranges specified in the manifest file, which means a dependency can silently upgrade to a new release between environments or over time. This silent drift can introduce regressions, behavioral changes, or vulnerabilities without any corresponding change in the project's source code or manifest, making the root cause difficult to identify.

Who it's relevant to

Software Developers
Developers working in any language ecosystem that uses a package manager benefit from committing lockfiles to source control. Lockfiles ensure that a project builds consistently on a colleague's machine, in CI, and in production, eliminating a common class of 'works on my machine' issues caused by dependency version drift.
DevOps and Build Engineers
Engineers responsible for CI/CD pipelines rely on lockfiles to produce deterministic build outputs. Installing from a lockfile rather than re-resolving dependencies on every build reduces non-determinism and makes it easier to identify when a dependency change has been deliberately introduced versus when it occurred as an unintended side effect of an upstream registry update.
Security and AppSec Engineers
Lockfiles make the resolved dependency graph auditable and reviewable as part of standard code review, which is a meaningful control for catching unauthorized or unexpected dependency changes. However, security practitioners should understand that a lockfile does not independently detect malicious packages introduced at resolution time, and integrity guarantees are only as strong as the hash validation behavior of the package manager in use.
Security Auditors and Compliance Teams
Auditors can use committed lockfiles to reconstruct the exact dependency set present in a given release, supporting vulnerability analysis, license review, and software bill of materials generation. Because the lockfile captures transitive dependencies in addition to direct ones, it provides more complete visibility into the actual dependency graph than a manifest file alone.

Inside Lockfiles

Resolved Package Names
The exact names of all direct and transitive dependencies as resolved by the package manager at the time the lockfile was generated.
Pinned Versions
The specific version strings for every resolved package, eliminating the version range ambiguity present in the primary manifest file.
Integrity Hashes
Cryptographic checksums (typically SHA-512 or similar) for each package artifact, used to verify that the downloaded package matches what was recorded at lock time.
Resolved Registry URLs
The specific registry or source location from which each package was fetched, recording where the artifact originated rather than relying on default registry configuration at install time.
Dependency Graph Flattening
A record of the full transitive dependency tree, capturing not only direct dependencies but all nested dependencies and the relationships between them.
Package Manager Metadata
Tool-specific fields such as lockfile format version or engine identifiers that allow the package manager to correctly interpret and apply the lockfile across environments.

Common questions

Answers to the questions practitioners most commonly ask about Lockfiles.

Does committing a lockfile to version control mean my dependencies are secure?
Not automatically. Committing a lockfile ensures that dependency versions and resolved checksums are consistent across environments, but it does not guarantee those pinned versions are free of known vulnerabilities. A lockfile records what was resolved at a point in time. The packages it pins may later have disclosed vulnerabilities, or may have already had undisclosed ones at the time of pinning. Regular auditing of lockfile contents against vulnerability databases is still required.
Does a lockfile protect against dependency confusion or substitution attacks?
Partially, but not completely. Lockfiles that record cryptographic checksums allow package managers to verify that the downloaded package matches what was previously resolved, which can detect substitution of a known package with a tampered one. However, a lockfile does not prevent a malicious package from being resolved in the first place if it was already present in the registry at resolution time. Dependency confusion attacks that succeed during the initial resolution phase may be recorded into the lockfile rather than caught by it.
Should lockfiles be committed to version control for all project types?
For applications, yes, lockfiles should typically be committed so that all contributors, CI systems, and deployment environments use identical resolved dependencies. For reusable libraries, the recommendation varies by ecosystem. In some ecosystems, committing a library lockfile can cause downstream consumers to ignore it, leading to inconsistent behavior. Practitioners should follow ecosystem-specific guidance for library projects.
How often should a lockfile be updated, and what is the risk of not updating it?
Lockfiles should be updated on a regular cadence and whenever dependency vulnerabilities are disclosed that affect pinned versions. Leaving a lockfile unchanged for extended periods increases the likelihood that pinned packages contain known, unpatched vulnerabilities. Automated tools can monitor lockfile contents against vulnerability advisories and open pull requests when updates are needed, reducing the manual burden of keeping lockfiles current.
What should I verify when a lockfile is modified in a pull request?
Reviewers should verify that the changed entries correspond to intentional dependency updates or additions, that no unexpected transitive dependencies have been introduced or changed, and that checksums are present and have not been removed. Unexplained additions of new packages, version downgrades, or removed integrity hashes in a lockfile diff are indicators that warrant closer investigation before merging.
Can I rely on a lockfile alone to enforce software supply chain policy, or do I need additional controls?
A lockfile is one control in a broader software supply chain security posture, not a sufficient standalone policy enforcement mechanism. Lockfiles help with reproducibility and integrity verification at install time, but organizations typically also need complementary controls such as private artifact registries, registry scoping configuration, continuous vulnerability scanning of lockfile contents, and provenance verification to address the full range of supply chain risks.

Common misconceptions

Committing a lockfile to version control is optional or only relevant for application projects.
Committing lockfiles is recommended for application projects to ensure reproducible installs across all environments and contributors. For library projects the convention differs, but for deployed applications the lockfile should typically be treated as a required artifact in version control.
A lockfile guarantees that installed packages are free of vulnerabilities or malicious code.
A lockfile guarantees version and integrity consistency relative to what was recorded at lock time. It does not verify that the pinned packages are themselves safe. A package that was malicious or vulnerable when the lockfile was generated will remain pinned to that state unless the lockfile is explicitly updated and the new resolution is reviewed.
Integrity hashes in a lockfile provide the same assurance as independently verifying packages against a trusted source.
Integrity hashes in a lockfile confirm that a downloaded artifact matches what was recorded when the lockfile was created. They do not independently attest to the trustworthiness of the original package. If the lockfile itself was tampered with or generated from a compromised registry response, the hashes will reflect the compromised state.

Best practices

Commit lockfiles to version control for all application projects and treat changes to the lockfile as meaningful, reviewable diffs in pull requests.
Use package manager commands that perform deterministic, lockfile-respecting installs in CI/CD pipelines (such as 'npm ci' or 'pip sync') rather than commands that may update or regenerate the lockfile during build.
Review lockfile changes as part of the code review process, paying attention to unexpected transitive dependency additions, version changes, or registry URL changes that were not anticipated from the corresponding manifest change.
Establish a routine process for updating lockfiles deliberately, such as scheduled dependency update reviews, rather than allowing ad-hoc or unreviewed regeneration of the lockfile.
Verify that your registry configuration is consistent and explicitly scoped so that resolved registry URLs recorded in the lockfile reflect intended sources and reduce exposure to dependency confusion attacks.
Integrate lockfile integrity checks into security tooling pipelines so that modifications to the lockfile outside of authorized update workflows are flagged before deployment.