Skip to content
Latchkey

npm dedupe Has No Effect / Reintroduces Duplicates - Fix in CI

npm dedupe rewrites the tree to share compatible dependency versions, but it edits package-lock.json - and npm ci installs the lockfile exactly as committed. If you dedupe locally but do not commit the lockfile, CI reinstalls the duplicated tree.

What this error means

After running npm dedupe, CI still installs multiple copies of a dependency, or a bundle stays large. Either the deduped lockfile was never committed, or the version ranges in the tree cannot be collapsed to a single version.

npm output
$ npm dedupe
# locally the tree shrinks, but in CI:
$ npm ci && npm ls some-dep
app@1.0.0
├── some-dep@1.2.0
└─┬ other@2.0.0
  └── some-dep@1.1.0   # still duplicated (lockfile not committed)

Common causes

The deduped lockfile was not committed

npm dedupe changes package-lock.json. npm ci installs strictly from the committed lockfile, so without committing the deduped lock, CI rebuilds the old duplicated tree.

Ranges genuinely cannot collapse

If two dependents require incompatible version ranges, both copies must coexist - dedupe cannot merge them, so duplicates legitimately remain.

How to fix it

Commit the deduped lockfile

Run dedupe, then commit the updated lockfile so CI installs the deduped tree.

Terminal
npm dedupe
npm ls some-dep        # confirm fewer copies
git add package-lock.json
git commit -m "chore: dedupe dependencies"

Collapse incompatible ranges deliberately

  1. Use npm ls <pkg> to see why two versions coexist.
  2. Align the dependents’ ranges, or add an overrides entry to force one version (when safe).
  3. Re-run dedupe and commit the lockfile.

How to prevent it

  • Commit the lockfile after running npm dedupe.
  • Use overrides to force a single version when ranges allow.
  • Inspect duplicates with npm ls before assuming dedupe failed.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →