← All Articles

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 want

Fix 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@latest

This 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-deps

This 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=true

Fix 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.