npm ERESOLVE "unable to resolve dependency tree": what it means and how to fix it
You ran npm install or npm ci and got npm ERR! code ERESOLVE. It looks scary, but it's one specific problem: two packages disagree about which version of a third package they need. Here's how to read it and fix it properly.
What the error is actually saying
Since npm 7, npm installs peer dependencies for you and refuses to continue if they conflict. A typical message looks like this:
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! Found: [email protected]
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^17.0.0 || ^18.0.0" from [email protected]
Read it as three facts:
- Found: what you have, here React 19.
- peer … from: which package is complaining, here
some-library. - The range it wants: React 17 or 18. So
[email protected]hasn't declared support for React 19.
The fix is always one of: upgrade the complaining package, downgrade the thing it complains about, or tell npm the mismatch is fine.
Fix 1: upgrade the package that's complaining (best)
Most of the time a newer version of the complaining package already supports what you have.
npm view some-library peerDependencies
npm view some-library versions --json
If a newer version lists your version in its peer range, install it: npm install some-library@latest. Check its changelog for breaking changes first.
Fix 2: match the version it expects
If the library hasn't caught up yet and you don't need the newer version of the other package, install the version it supports, for example npm install react@18 react-dom@18. This is the safest choice for production until the library updates.
Fix 3: an override, when you know it works
If you've tested the library with your newer version and it works (peer ranges are often just not updated yet), tell npm explicitly in package.json:
"overrides": {
"some-library": {
"react": "$react"
}
}
$react means "use the same version as my direct dependency." This is scoped to one package and documented in your repo, which is much better than a global flag.
About --legacy-peer-deps and --force
--legacy-peer-depsgoes back to the npm 6 behavior and ignores peer dependencies entirely. It makes the error go away, but also hides real conflicts. If you use it, putlegacy-peer-deps=truein a committed.npmrcso CI and teammates install the same tree.--forceinstalls anyway and can leave you with a broken tree. Avoid it.
"It works locally but fails in CI"
- Different npm versions. Peer-dependency handling changed in npm 7 and again in later versions. Check
npm -vlocally and in the CI log, and pin the Node version in CI. - A local
.npmrcthat isn't committed. If you setlegacy-peer-depson your machine only, CI won't have it. - A stale lock file.
npm ciinstalls exactly what's inpackage-lock.json. If the lock file was made with different flags, regenerate it once: deletenode_modulesandpackage-lock.json, runnpm install, test, and commit the new lock file.
Still stuck?
Upgrades with tangled peer dependencies are one of the things we fix for a flat price: $99 to get a failing build green again, or $249–$499 for a full framework upgrade with tests passing. You get a pull request and a note on what changed, and you pay only after it works. The work is done by an AI coding system (Anthropic's Claude).