Diagnosing and Fixing npm ERESOLVE Peer Dependency Errors
A step‑by‑step diagnostic guide for npm ERESOLVE peer‑dependency errors, with checks, fixes tied to findings, and verification steps.
23 Nov 2025, 15:55 UTC

Recognizable condition
When you run npm install or npm ci in a JavaScript/TypeScript project, the command exits with status 1 and the terminal shows an ERESOLVE error. The message typically mentions "unable to resolve dependency tree" and cites a peer dependency mismatch, for example:
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
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! peer react@"^16.8.0 || ^17.0.0" from some-ui-lib@2.3.4
npm ERR! node_modules/some-ui-lib
npm ERR! some-ui-lib@"^2.3.4" from the root project
npm ERR! Conflicts: some-ui-lib requires react@^16.8.0 || ^17.0.0 but you have 18.2.0
The useful takeaway is: the error tells you exactly which package expects a different version of a peer dependency than what is currently installed.
Cause / diagnostic table
| Symptom | Likely cause |
|---|---|
| ERESOLVE with a specific package and peer dependency | Mismatched peer dependency version: the dependent package declares a peer dependency range that the installed version does not satisfy. |
| Error appears after a version bump or merge | Lockfile drift: package-lock.json (or npm-shrinkwrap.json) records a version that violates the peer constraint. |
| Error persists across clean installs | Strict peer‑dependency policy (npm v7+) treats peer dependencies as regular dependencies, so any version outside the declared range blocks installation. |
Ordered checks
- Inspect the full error output – locate the package name after "While resolving:" and the peer dependency line that shows the required range and the found version.
- Check the installed version of the peer dependency – run (in the project root, with read access to
node_modules):
Replacenpm ls <peer-package><peer-package>with the name from the error (e.g.,react). The command prints the version currently resolved in the tree. - Examine
package.jsonandpackage-lock.json– look for:- The dependent package (
some-ui-libin the example) and its version range. - The peer dependency entry inside that package’s
package.json(you can view it vianpm view some-ui-lib peerDependencies). - The locked version of the peer dependency in
package-lock.json(npm ls reactshows the same).
- The dependent package (
- Identify recent changes – if you have a VCS, run:
Look for edits that upgraded/downgraded the peer dependency or added/removed the dependent package.git diff --name-only HEAD~1 package.json package-lock.json - Verify npm version – run:
npm v7+ enforces strict peer resolution; older versions (< 7) would have allowed the install but could cause runtime issues.npm -v
Fixes tied to findings
When you control the dependent package
If the package that declares the peer dependency is under your ownership (e.g., an internal UI library), adjust its peer‑dependency range to accept the version you have:
- Edit the package’s
package.json: - Commit the change, then run
npm installin the consuming project.
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
When you do not control the dependent package
Two practical options:
- Align the peer version – downgrade or upgrade the peer dependency to satisfy the declared range. For the example, you could run:
Then verify withnpm install react@^17.0.0 --save-exactnpm ls reactthat the version falls within^16.8.0 || ^17.0.0. - Bypass strict enforcement (last resort) – use the legacy peer‑deps flag:
This tells npm to ignore peer conflicts and install the tree anyway. Risk: the installed version may not actually satisfy the peer’s API, leading to runtime errors. Only use this after confirming the application works in a test environment.npm install --legacy-peer-deps
Resolving lockfile drift
If the lockfile holds a version that violates peer constraints after a manual edit or merge conflict, regenerate it:
- Delete the lockfile:
- Re‑install:
rm package-lock.json # or npm-shrinkwrap.json
npm install
This creates a fresh lockfile that respects the version ranges in package.json. Commit the new lockfile only after verifying the install succeeds.
Escalation criteria
Escalate to a senior engineer or open an issue with the dependent package’s maintainers when:
- The peer dependency is a major framework (e.g., React, Vue) and aligning versions would break other parts of the application.
- Repeated attempts to adjust versions still produce ERESOLVE errors, indicating a deeper version‑range incompatibility.
- You must use
--legacy-peer-depsand need to document the risk for downstream consumers. - Remove
node_modulesand the lockfile (if you regenerated it):rm -rf node_modules package-lock.json npm install - Watch for the absence of ERESOLVE in the output.
- Run
npm ls <peer-package>and ensure the printed version satisfies the peer range reported earlier. - Start the dev server or run the test suite to catch any runtime incompatibilities that may have been hidden by the fix.
In these cases, consider creating a fork of the dependent package with an updated peer‑dependency range, or submit a pull request to the upstream project.
Verification
After applying any fix, confirm the resolution:
If you used --legacy-peer-deps, additionally run:
npm audit
to check for newly introduced vulnerabilities and plan a future upstream update.
Limitations and practical checks
Even after the install succeeds, a version mismatch can still cause subtle bugs if the dependent package relies on APIs that changed between the declared range and the installed version. The only reliable way to detect this is through functional testing (unit, integration, or end‑to‑end) and manual verification of features that use the peer dependency.
To quickly check that the installed peer version is within the allowed range without re‑running the full install, you can use:
npm list <peer-package> --json | jq '.dependencies["<peer-package>"].version'Replace
<peer-package>with the actual name (e.g.,react) and ensurejqis installed. Compare the output to the range using a simple semver check in your CI scripts.Rollback (if needed)
Only the steps that modify state (
node_modules, lockfile, orpackage.json) require a rollback strategy:
- If you edited a package’s
package.json, revert the change with Git (git checkout -- package.json) and re‑install. - If you deleted the lockfile, restore it from the repository (
git checkout -- package-lock.json) and runnpm installagain. - If you used
--legacy-peer-depsand wish to revert to strict behavior, simply remove the flag and reinstall; the lockfile will be updated on the next clean install.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.