🎉 DevOps Interview Prep Bundle is live — 1000+ Q&A across 20 topicsGet it →
All Articles

npm ERESOLVE Dependency Conflict: Fix in 5 Minutes

npm install failing with 'ERESOLVE unable to resolve dependency tree'? Here is exactly how to read the conflict, find the real peer dependency mismatch, and fix it without blindly reaching for --force.

Shubham4 min read
Share:Tweet

ERESOLVE errors are npm being stricter about peer dependencies since v7 — the error is verbose and looks scary, but it always tells you exactly which two packages disagree. Here is how to read it and fix the real cause instead of reaching for --force and hoping.

Step 1: Read the Actual Conflict

bash
npm install
 
# npm ERESOLVE unable to resolve dependency tree
# Found: react@18.2.0
# node_modules/react
#   react@"^18.2.0" from the root project
#
# Could not resolve dependency:
# peer react@"^17.0.0" from some-old-library@2.1.0
# node_modules/some-old-library
#   some-old-library@"^2.1.0" from the root project

This tells you exactly the conflict: your project wants React 18, but some-old-library@2.1.0 declares a peer dependency on React 17 and hasn't been updated to support 18.

Cause 1: A Dependency's Peer Requirement Is Genuinely Outdated

bash
# Check if a newer version of the conflicting package supports your version
npm view some-old-library versions --json | tail -20
npm view some-old-library@latest peerDependencies

Fix — if a newer version supports React 18, upgrade it:

bash
npm install some-old-library@latest

If no version supports your target yet, and the library still works fine at runtime despite the peer mismatch:

bash
npm install --legacy-peer-deps

--legacy-peer-deps reverts to npm 6's looser peer dependency resolution — it does not fix the underlying incompatibility, it just stops npm from blocking the install over it. Only use this when you've actually confirmed the library works fine with your React version despite the declared peer range (many libraries are more compatible than their stale peerDependencies field claims).

Cause 2: Two Unrelated Dependencies Both Constrain a Shared Package

bash
# npm ERESOLVE unable to resolve dependency tree
# Found: typescript@5.4.0
# Could not resolve dependency:
# peer typescript@"<5.0.0" from old-eslint-plugin@3.0.0
# Could not resolve dependency:
# peer typescript@">=5.3.0" from new-testing-lib@2.0.0

Here, two of your dependencies want incompatible TypeScript ranges — neither is wrong, they just haven't converged yet.

bash
# Check which one is more actively maintained / has a compatible update available
npm view old-eslint-plugin versions --json | tail -10

Fix — usually the older, less-maintained package is the one to replace or upgrade:

bash
npm install old-eslint-plugin@latest    # if it's been updated to support TS 5.x
# or
npm uninstall old-eslint-plugin && npm install newer-alternative-plugin

Cause 3: --force Masking a Real Runtime Incompatibility

bash
npm install --force
# Installs successfully, but...
npm run build
# TypeError: someFunction is not a function

--force installs the exact versions you asked for regardless of any peer conflict, including genuine incompatibilities that will break at runtime, not just at install time. This is different from --legacy-peer-deps — force is more aggressive and more dangerous.

Fix — don't reach for --force as a first response. Use it only after confirming the conflict is cosmetic:

bash
# Check the actual behavior before deciding --force is safe
npm ls react    # See the full resolved tree
npm install --dry-run    # Preview what would actually be installed without committing

Cause 4: Lockfile Out of Sync With package.json After a Manual Edit

bash
# If you hand-edited package.json without running npm install after,
# the lockfile can reflect a resolution that no longer matches
npm ci
# npm ERESOLVE ...

npm ci is stricter than npm install — it requires the lockfile to exactly satisfy package.json, with no resolution flexibility.

Fix — regenerate the lockfile locally, then commit it:

bash
rm package-lock.json
npm install
git add package-lock.json
git commit -m "Regenerate lockfile after dependency updates"

Cause 5: Monorepo Workspace Hoisting Conflict

bash
# In an npm workspaces monorepo, two packages requiring different
# major versions of the same dependency can't both hoist to root
npm ERESOLVE unable to resolve dependency tree
# ...conflicting requirements from packages/api and packages/web

Fix — pin the conflicting dependency per-workspace instead of relying on hoisting:

json
// packages/api/package.json
{
  "dependencies": {
    "some-lib": "1.x"
  }
}
json
// packages/web/package.json
{
  "dependencies": {
    "some-lib": "2.x"
  }
}

npm workspaces will install both versions locally within each package when hoisting to root isn't possible — this is expected behavior, not a bug, once the versions genuinely diverge.

Decision Tree

bash
npm install                          # read the exact conflict first, always
npm view PACKAGE@latest peerDependencies   # check if a newer version resolves it
npm install PACKAGE@latest            # prefer upgrading the outdated package
npm install --legacy-peer-deps        # only after confirming actual compatibility
npm install --force                   # last resort, verify with tests immediately after

More CI/CD troubleshooting? Read our GitHub Actions cache not working fix and CI/CD pipeline debugging guide.

🔧

Today I Fixed

Short real fixes from production — posted daily

Browse fixes
Newsletter

Stay ahead of the curve

Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.

Related Articles

Comments