npm ERR! ERESOLVE: peer dependency conflicts — the complete fix guide
Symptom: npm install refuses to run
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: my-app@1.0.0
npm ERR! Found: react@18.2.0
npm ERR! node_modules/react
npm ERR! react@"18.2.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^17.0.0" from some-lib@2.1.0
npm 7+ enforces peer dependency resolution during install. Older versions just warned — now it's a hard stop.
What are peer dependencies (and why npm cares)
A peer dependency says: "I need this package to exist in the host app, but I won't install it myself." It exists so plugins and libraries share a single copy of the host framework instead of bundling their own.
When two packages disagree on the peer version (one wants React 17, another wants React 18), npm can't satisfy both → ERESOLVE error. This is not a bug — it's npm telling you there's a real compatibility risk.
Four resolution strategies (in order of safety)
Strategy 1: Fix the actual version conflict
Read the error carefully — it tells you exactly which package wants which version. Often the fix is simply upgrading (or downgrading) one of your direct dependencies so all peer ranges overlap:
# See what your current versions are
npm ls react
# Update the conflicting package
npm install some-lib@latest
Strategy 2: --legacy-peer-deps (quick unblock)
npm install --legacy-peer-deps
This tells npm to behave like npm 6: install anyway, warn about conflicts but don't block. Trade-off: the incompatibility is real — the conflicting packages might crash at runtime.
Make it permanent in .npmrc (project root):
legacy-peer-deps=true
When to use: you know the peer conflict is harmless (the library works fine with a newer version despite declaring an older peer range). Very common with React — many libs declare peer: react@^17 but work perfectly on 18.
Strategy 3: overrides in package.json (npm 8.3+)
Force a specific version for a transitive dependency:
{
"overrides": {
"some-lib": {
"react": "^18.2.0"
}
}
}
This tells npm: "I know some-lib wants React 17, but I'm overriding that to React 18." More precise than legacy-peer-deps.
Strategy 4: Manual resolution with dedupe
npm dedupe
Reduces duplication in node_modules by flattening compatible versions. Sometimes resolves conflicts by consolidating to a single version that satisfies all ranges.
When NOT to use --force
npm install --force is different from --legacy-peer-deps. Force installs everything regardless of conflicts, potentially creating multiple versions of the same package. This can lead to:
- Two Reacts in
node_modules→ hooks break ("Invalid hook call") - Type incompatibilities at runtime
- Unpredictable behavior
Never use --force on a project with React hooks — multiple React copies is the #1 cause of "Invalid hook call" errors.
Debugging tools
# See the dependency tree
npm ls react
# See why a package is installed
npm explain some-lib
# Check for duplicate versions
npm ls react | grep -c "react@"
Prevention
- Update regularly — small version bumps are easier than big jumps
- Use
npm outdatedto see what's behind - Read peer ranges before adding a library —
npm info some-lib peerDependencies
FAQ
Why did this start happening after upgrading npm?
npm 7+ (released 2020) changed peer dependency handling from warn-only to hard-enforce. Projects that installed fine on npm 6 hit ERESOLVE on npm 7+.
Can I just delete package-lock.json and retry?
Sometimes works, but dangerous: it allows all transitive dependencies to float to their latest versions, potentially introducing new breaking changes. Only do this if you're also updating all direct dependencies.
What's the difference between dependencies, devDependencies, and peerDependencies?
dependencies: "I need this to run, install it for me"devDependencies: "I need this to build/test, install it for me"peerDependencies: "I need the HOST APP to have this installed — I won't install it, but I require it at runtime"
Provided by ToolVault. Related: npm registry mirror guide, Cannot find module fix. See the homepage for more developer tools.
Related Tools
Related Articles
Permission denied (publickey): 6 Reasons Git Push Fails Over SSH (and the Fix for Each)
git clone or push rejected with Permission denied (publickey) fatal: Could not read from remote repository? Covers missing keygen, key not loaded in the agent, public key not added to GitHub/GitLab, multi-account key routing with ~/.ssh/config, deploy key limits, and wrong remote URLs — with ssh -v diagnostics.
error:0308010C digital envelope routines::unsupported — Fixing Node 17+ Breakage in Older Projects
Node 17+ crashes webpack 4 builds with error:0308010C:digital envelope routines::unsupported because OpenSSL 3.0 removed MD4. Three fixes compared: --openssl-legacy-provider quick unblock, upgrading to webpack 5 as the real fix, and pinning Node 16 as a stopgap.
ECONNREFUSED: Connection Refused — 5 Causes Explained (Including Docker)
Node, Java, or curl reporting connect ECONNREFUSED 127.0.0.1:3306? It means nothing is listening on that port. Covers service not running, wrong port, 127.0.0.1-only binding, Docker container networking, and firewall REJECT rules — with ss/lsof diagnostic commands.