Join our Newsletter — 33% off our NHI Course

When should teams prioritise lockfiles over manually vendoring source code in their application tree?

Teams should prioritise lockfiles when they want consistent dependency resolution without the maintenance burden of copying source into the codebase. Vendoring makes it harder to see exact versions, encourages local edits to library code, and complicates upgrades. A lockfile preserves version certainty while still letting package managers resolve dependencies cleanly across environments.

Why lockfiles are the right default for reproducible dependency resolution

Lockfiles are the better choice when the goal is to make dependency resolution repeatable without turning third-party code into part of your own source tree. They record the exact resolved package graph while leaving the package manager in control of fetching, integrity checks, and environment-specific installation details. That gives teams version certainty without copying library code into the application.

That distinction matters because manually vendored code tends to blur what is first-party and what is imported, which makes upgrades, code review, and ownership harder. A lockfile keeps the dependency boundary visible and makes it easier to reason about changes when a package is updated, removed, or replaced.

A lockfile also reduces the temptation to patch library source locally just to make a build pass. When a change must be carried, teams can see it as an explicit fork or patch decision instead of an accidental edit buried in copied dependencies. That improves traceability and makes future reconciliation with upstream versions much cleaner.

Where vendoring source code creates more operational drag than control

Vendoring can be useful in narrow cases, but for most application builds it creates a maintenance problem that outweighs the convenience. Once source is copied into the tree, the team inherits the burden of tracking updates, comparing diffs against upstream, and making sure local changes do not silently diverge from the published package.

The biggest drawback is version ambiguity. With vendored code, it is often harder to tell which release is actually present, whether it includes upstream fixes, and whether multiple copies of the same dependency exist across the repository. That can complicate debugging, incident response, and supply-chain review because the dependency state is no longer concentrated in one resolution manifest.

Vendoring also expands the review surface. Code owners and security reviewers have to inspect copied third-party source along with any local modifications, which increases noise and creates a greater chance of missing an important change. A lockfile keeps the focus on a smaller set of deliberate dependency updates rather than a larger set of copied files.

When the choice should swing back toward vendoring

Lockfiles are the default for most teams, but vendoring still has a place when build reproducibility must survive environments with limited or no package registry access, or when upstream availability is an operational dependency you cannot accept. In those cases, local copies can act as a resilience measure rather than a convenience feature.

Teams may also vendor when they need to apply a long-lived patch that cannot be expressed cleanly as a normal dependency override, or when their packaging model requires source distribution as part of a controlled release artifact. Even then, the trade-off should be explicit: vendoring buys independence at the cost of more manual maintenance and more drift risk.

If the main requirement is deterministic builds, lockfiles are usually the cleaner mechanism because they preserve repeatability without duplicating dependency source. If the main requirement is to own and modify third-party code locally, vendoring is a deliberate fork-like decision and should be treated that way.

Risk and Threat Considerations

Vendored dependencies can hide stale, patched, or locally modified code in a way that makes supply-chain review and vulnerability response slower. The risk is not just update friction, it is also losing clarity over what code is running, which version introduced the issue, and whether a local edit has changed the security profile of the library.

Failure mechanism: Copying source into the application tree can conceal upstream provenance, obscure exact versions, and leave teams with multiple divergent copies of the same library. That weakens patch management and makes it easier for unsafe modifications or unreviewed fixes to persist.

Impact: Security fixes can be delayed, audits become harder, and incident triage takes longer because defenders must reconstruct dependency lineage from copied code rather than a single resolved manifest.

Standards & Framework Alignment

This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.

SLSA, CIS Controls v8 and OWASP SAMM set the governance and control requirements practitioners need to meet.

Framework Control / Reference Relevance
SLSA Supply Chain Levels for Software Artifacts Lockfiles support reproducible dependency provenance in the build supply chain.
Recommendation — Pin dependencies and verify build inputs to preserve artifact provenance.
CIS Controls v8 CIS-16 — Application Software Security The choice affects how teams control and review third-party code in applications.
Recommendation — Control third-party code handling and review dependencies before release.
OWASP SAMM Software Assurance Maturity Model Dependency handling and update discipline are part of secure software development practice.
Recommendation — Standardise dependency management so updates are traceable and reviewable.

Practitioner Guidance

What to verify: Treat the lockfile as the authoritative record of what was actually resolved, and verify that build and deploy systems use it consistently rather than re-resolving dependencies opportunistically. If the lockfile and manifest disagree, resolve that mismatch before trusting the build.

Decision rule: Prefer vendoring only when you need an explicit, durable fork or when your environment cannot rely on package retrieval at build time. If the use case is simply repeatable installs, lockfiles give you the cleaner control point with less maintenance overhead.

Practitioner takeaway: Use vendoring only when you are intentionally taking ownership of third-party code; otherwise, lockfiles provide the more auditable and lower-drift path to reproducible builds.