Package Manager Lockfile Guide: Resolve npm, pnpm, Yarn, and Composer Dependency Conflicts
npmpnpmYarnComposerLockfilesDependenciesCI/CDJavaScript

Package Manager Lockfile Guide: Resolve npm, pnpm, Yarn, and Composer Dependency Conflicts

CCode Harvest Editorial Team
2026-11-09
6 min read

A practical checklist for fixing npm, pnpm, Yarn, and Composer lockfile conflicts, version drift, peer errors, and reproducible CI installs.

Lockfile conflicts are usually symptoms of a mismatch between dependency declarations, package-manager versions, runtime constraints, or branch history. This guide provides a repeatable checklist for diagnosing and safely fixing npm, pnpm, Yarn, and Composer dependency problems without accidentally changing more of the dependency tree than intended.

Overview

A lockfile records the resolved dependency graph used by an application: package versions, transitive dependencies, integrity information, registry references, and sometimes workspace or peer-dependency metadata. The manifest describes what a project allows or requests; the lockfile records what the project actually resolved.

Common lockfiles include package-lock.json for npm, pnpm-lock.yaml for pnpm, yarn.lock for Yarn, and composer.lock for Composer. A healthy project normally commits its lockfile for applications and services so local development and continuous integration can use the same dependency resolution. Libraries may follow different publishing conventions, but their repository workflow should still be deliberate.

Use this basic model when investigating a failure:

Manifest changes  ->  dependency resolution  ->  lockfile update  ->  install
     package.json       npm/pnpm/Yarn             package-lock       node_modules
     composer.json      or Composer              yarn.lock          vendor/

The safest repair is usually not to delete the lockfile immediately. First identify which input changed, confirm the package manager and runtime versions, reproduce the problem in a clean working tree, and regenerate only the files that are supposed to change.

ToolManifestTypical lockfileReproducible CI install
npmpackage.jsonpackage-lock.jsonnpm ci
pnpmpackage.jsonpnpm-lock.yamlpnpm install --frozen-lockfile
Yarnpackage.jsonyarn.lockUse the immutable or frozen mode supported by the repository's Yarn generation.
Composercomposer.jsoncomposer.lockcomposer install --no-interaction --prefer-dist

Do not mix package managers casually. A repository that has chosen pnpm should not receive a newly generated npm lockfile just because npm is available on a developer's machine.

Checklist by scenario

After changing direct dependencies

  1. Confirm the intended edit in package.json or composer.json. Check whether the change is a runtime dependency, development dependency, peer dependency, or platform requirement.
  2. Run the package manager declared by the repository. Look for the packageManager field, contributor documentation, lockfile, workspace configuration, or project tooling.
  3. Update the lockfile through the package manager rather than editing generated sections by hand. For a targeted npm change, use an appropriate npm install command. For pnpm, use pnpm install or a targeted pnpm add. For Composer, use composer require or composer update with a deliberate package selection.
  4. Review the complete diff. A small manifest change can legitimately update transitive packages, but unexplained broad changes deserve investigation.
  5. Run the project's validation, tests, build, and production-like install before committing.

After a Git merge conflict

  1. Do not choose the current branch's or incoming branch's lockfile wholesale without understanding both dependency changes.
  2. Resolve the manifest files first. They express the desired dependency requirements and should be treated as the source of intent.
  3. Regenerate the lockfile with the repository's package manager and a clean dependency directory when practical. This lets the resolver construct one coherent graph instead of preserving conflict-marker decisions.
  4. Inspect whether unrelated packages, peer resolutions, workspace entries, or platform constraints changed.
  5. Commit the regenerated lockfile together with the manifest resolution, then run the same locked install used by CI.

When CI rejects a lockfile

A frozen or immutable install fails when the lockfile does not satisfy the manifest or when the environment cannot reproduce the recorded resolution. Compare the CI package-manager version, Node or PHP version, operating system assumptions, registry configuration, and workspace settings with local development.

Do not solve a CI mismatch by disabling frozen installation as a first response. Instead, regenerate the lockfile with the intended toolchain, verify it locally using the locked command, and commit the result. If the failure is caused by a legitimate platform difference, document the constraint and decide whether the dependency or CI matrix needs adjustment.

For peer-dependency errors

  1. Read the full error, including the package requesting the peer and the version range it accepts.
  2. Check the installed direct version and the lockfile's resolved version. A manifest range can appear compatible while another package's peer range is not.
  3. Prefer installing a compatible direct dependency or upgrading the package that declares the restrictive peer range.
  4. Use an override, resolution, or equivalent feature only when the compatibility is understood and tested.
  5. Treat force or legacy-peer-dependency options as temporary diagnostics unless the project has a documented reason to retain them.

For version drift or a broken local install

Record the package-manager version and runtime version, then compare the manifest and lockfile with version control. Remove only generated dependency directories such as node_modules or vendor when needed; do not remove the lockfile as a routine cleanup step. Reinstall with the locked CI command and compare the result with the previous working environment.

What to double-check

  • Package-manager identity: npm, pnpm, Yarn Classic, and modern Yarn do not interpret every setting or command in the same way. Follow the repository's declared version and configuration.
  • Runtime compatibility: Check the project's Node or PHP requirement, architecture, operating system, and enabled extensions. A valid lockfile cannot make an incompatible runtime work.
  • Workspace boundaries: In monorepos, determine whether one root lockfile controls all packages or whether the repository intentionally uses separate projects.
  • Registry and authentication: Private registries, scoped packages, mirrors, and credentials can make an otherwise valid lockfile fail during installation. Never commit tokens while diagnosing this.
  • Manifest and lockfile alignment: A changed version range, script-generated dependency, alias, patch, override, or platform requirement may require a lockfile update.
  • Diff size: Review additions, removals, integrity changes, and version jumps. A lockfile is generated, but its diff still communicates an important supply-chain change.
  • Application versus library behavior: Applications generally benefit from committed locks and locked deployments. Libraries should follow their ecosystem's publishing and testing expectations rather than copying an application workflow automatically.
  • Security review: A lockfile fix is not a substitute for reviewing newly introduced packages, scripts, licenses, or advisories. Inspect unexpected additions before merging.

Common mistakes

Deleting the lockfile first. This can replace a narrow repair with a large dependency reshuffle. Preserve the file, identify the cause, and regenerate intentionally.

Manually editing generated data. Removing conflict markers may produce syntactically valid text but an invalid or incomplete dependency graph. Resolve source manifests, then let the package manager recreate the lockfile.

Using a different package manager locally. Running npm in a pnpm or Yarn repository can create competing lockfiles and a dependency layout that CI does not use.

Updating everything to fix one package. Broad updates increase review scope and may introduce unrelated regressions. Prefer a targeted update when the package manager supports it, then expand only when constraints require it.

Ignoring toolchain versions. Lockfile formats and resolver behavior can vary across major tool versions. Pin or document the expected package-manager and runtime versions where reproducibility matters.

Accepting force flags permanently. Bypassing peer checks can hide a real incompatibility. Record why an exception is needed, test the affected code path, and revisit it during dependency maintenance.

Testing only the developer install. A successful install with an existing dependency directory does not prove a clean deployment works. Test from a clean environment using the same locked command as CI.

When to revisit

Return to this checklist whenever a dependency manifest changes, a branch introduces a lockfile conflict, a clean CI install fails, or a runtime or package-manager major version changes. It is also useful before planned maintenance cycles: review the repository's supported runtimes, package-manager command, lockfile policy, and CI cache behavior before starting a large update.

After resolving a difficult conflict, leave a short note in the repository documentation or pull request describing the cause, the regeneration command, and any compatibility decision. That record reduces repeated investigation when the same dependency is updated later.

For the next repair, use this compact sequence: identify the package manager, preserve the lockfile, resolve manifest intent, regenerate with the correct toolchain, inspect the diff, run a clean locked install, and test the application. This process is slower than deleting files and retrying, but it produces a dependency graph that is easier to review and more likely to behave consistently across developer machines and CI.

Related Topics

#npm#pnpm#Yarn#Composer#Lockfiles#Dependencies#CI/CD#JavaScript
C

Code Harvest Editorial Team

Developer Tools Editor

Senior editor and content strategist. Writing about technology, design, and the future of digital media. Follow along for deep dives into the industry's moving parts.