Skip to content

npm errornpm: “ERESOLVE unable to resolve dependency tree”

npm install fails with npm error code ERESOLVE, ERESOLVE unable to resolve dependency tree (or could not resolve), followed by Found: react@19.0.0 and Could not resolve dependency: peer react@"^18.0.0" from some-package. Since npm 7, npm installs peer dependencies and refuses a tree where two packages want incompatible versions of the same peer.

Short answer

Read the Found and Could not resolve dependency lines: they name the package whose peer range is too old (or too new) for what you have. Upgrade that package to a release that supports your version, or pick versions that satisfy both ranges. If no compatible release exists and you have checked it works, pin the peer with overrides in package.json. Use --legacy-peer-deps only as a last resort, and never --force as a habit.

Which packages disagree, and the fix

  1. 01

    A package with an outdated peer range

    The usual case: you upgraded React, Next.js, ESLint or TypeScript, and a plugin still declares a peer range for the old major version. Check whether a newer version of that plugin exists, and upgrade it.

    npm view some-package peerDependencies
    npm install some-package@latest
  2. 02

    No compatible release yet: overrides

    “Overrides provide a way to replace a package in your dependency tree with another version, or another package entirely.” npm Docs, package.json: overrides

    If the plugin works with your version but has not updated its range, override the peer for that package in the root package.json, then run a clean install and test. The "$react" value reuses the react version your root package.json already declares, so react must be listed there.

    {
      "overrides": {
        "some-package": {
          "react": "$react"
        }
      }
    }
  3. 03

    --legacy-peer-deps, and why it is a last resort

    “Use of legacy-peer-deps is not recommended, as it will not enforce the peerDependencies contract that meta-dependencies may rely on.” npm Docs, npm config: legacy-peer-deps

    It makes npm behave like npm 6 and skip peer dependencies entirely, so the install succeeds even when versions really are incompatible. If you use it, put it in .npmrc so every machine and CI install the same tree, and plan to remove it.

    # .npmrc
    legacy-peer-deps=true
  4. 04

    It works locally but fails in CI or on Vercel

    A local node_modules or an .npmrc on your machine can hide the conflict. Delete node_modules, run npm ci (which installs exactly what the lockfile says), and commit the lockfile and any .npmrc the project needs.

Checked against the vendor’s docs on : npm Docs: config (legacy-peer-deps); npm Docs: package.json (overrides).

Rather hand it over?

Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.

Related: Vercel “npm run build exited with 1” · npm and pnpm “ELIFECYCLE” · npm “EACCES: permission denied”

Questions

More on this error

What is the difference between --force and --legacy-peer-deps?

Both get past the error. --legacy-peer-deps ignores peer dependencies; --force accepts conflicting versions and can install them anyway. Neither checks that the result works, so prefer fixing the versions.

Why did npm 6 not complain?

npm 6 did not install peer dependencies automatically; it only warned. npm 7 and later install them, so conflicts that were warnings became errors.

Can you fix it for me?

If one bug is the whole problem, the App Fix Ticket covers it: a written diagnosis first, then the fix. If the app has more going on, the Launch Check is a written check of the whole app. Each issue found is rated critical, high, medium or low, with where it is and how it was confirmed. No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.

A different error?

Describe it and get a written quote

Send the error and what you were doing. You get a written scope, a fixed price and a timeline; Simon replies by email, usually within one business day.