npm ERR! ERESOLVE Unable to Resolve Dependency Tree — Every Fix, Ranked
What This Error Actually Means
npm ERESOLVE is npm saying: "package A needs react@^18, but the tree already contains react@19, and no version of A works with both." Since npm 7, peer dependency conflicts are hard errors instead of warnings — the error text is long, but it always contains the same three keys: the package that has the requirement, the version it wants, and the version already installed.
Read it like this: Could not resolve dependency: peer react@"^18.0.0" from [email protected] means some-lib was built for React 18 and hasn't shipped a React 19 version.
Quick Diagnosis
npm ls react # what version is actually installed
npm view some-lib peerDependencies # what does the lib wantFix 1: Use a Newer Version of the Conflicting Package (Best)
Most ERESOLVE errors are stale lockfiles fighting newly-published versions. Check if the complaining package has a newer release that supports your version:
npm view some-lib versions --json | tail -5
npm install some-lib@latestThis is the only fix that makes the conflict actually go away. If the package has no fixed version yet, move to fix 2.
Fix 2: --legacy-peer-deps (The Pragmatic Default)
npm install --legacy-peer-depsThis restores npm 6 behavior: peer conflicts become warnings, and npm installs what you asked for. It works because npm 6-era projects ran fine this way for years. The catch: no automatic peer resolution means incompatible packages can silently produce runtime errors — test after installing, don't just deploy.
To make it permanent for a project, add a .npmrc file:
legacy-peer-deps=trueFix 3: Resolutions / Overrides (When You Need Control)
When one transitive dependency drags in an old version, force it — npm's overrides field in package.json:
{
"overrides": {
"some-lib": {
"react": "^19.0.0"
}
}
}Then npm install again with a clean slate: rm -rf node_modules package-lock.json && npm install. This is the surgical option — pins the whole tree where you decide, no --legacy-peer-deps sprawl.
Fix 4: --force (Don't)
--force tells npm to install anyway even when the tree is provably broken. Occasionally it's the only thing that works for abandoned packages, but treat it as last resort: it hides real incompatibilities that surface as runtime crashes instead of install errors. If you're about to use it, take five minutes to check if fix 1 or 3 works first.
Why This Keeps Happening
Three structural causes: React's major versions (every React 18→19 migration broke half the ecosystem for a month), packages that declare peers too tightly ("[email protected]" when the code works on anything), and lockfiles created before a package published a breaking change. If you're on a monorepo, also check for multiple React copies — npm ls react should show one entry, not three.