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 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.
npm dedupe
npm ls some-dep # confirm fewer copies
git add package-lock.json
git commit -m "chore: dedupe dependencies"Collapse incompatible ranges deliberately
- Use
npm ls <pkg>to see why two versions coexist. - Align the dependents’ ranges, or add an
overridesentry to force one version (when safe). - 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.