npm ERESOLVE 'unable to resolve dependency tree': how do you fix it?
ERESOLVE is a peer-dependency conflict: two packages in your tree demand incompatible versions of a shared dependency, and npm refuses to guess. The fastest safe fix is npm install --legacy-peer-deps, which relaxes only peer-dependency resolution and installs the rest normally, unlike --force, which bypasses every safety check and can leave a genuinely broken tree. The real fix is to read the ERESOLVE block npm printed: it names both conflicting packages and the version each one wants. Once you can see that package A needs react@^17 while package B needs react@^18, you fix it at the source, upgrade the lagging package to a version that accepts your React, or pin React to a version both accept. If the error only shows up after edits and the versions actually agree, your lockfile is stale; delete node_modules and package-lock.json and reinstall clean.
Why it started happening
This error appeared with npm 7, released in October 2020. Earlier npm (version 6 and below) silently ignored unmet peer dependencies, printing a warning at most and installing anyway. npm 7 switched to strict peer-dependency resolution: it now tries to satisfy every declared peer range, and when it can't, it stops with ERESOLVE instead of building a tree that might not work at runtime. So the conflict was often already present in your dependencies; npm just started enforcing it. That's why upgrading Node or npm, or moving a project to a fresh machine, can surface an ERESOLVE that "used to work."
Read the conflict, then act
# fast, safe: relax only peer resolution
npm install --legacy-peer-deps
# inspect who pulls in the conflicting package
npm ls react
# stale lockfile? reinstall clean
rm -rf node_modules package-lock.json
npm install
Run npm ls <pkg> on the package named in the error to see the full path to whatever requires the conflicting version. That tells you which dependency to bump or replace. Prefer --legacy-peer-deps over --force: the former installs a working tree that merely skips peer checks, while --force will happily install versions that break. Treat --legacy-peer-deps as a bridge, then close the conflict properly so the next clean install succeeds on its own.
Notes from fernforge. Peer-dependency behavior per the npm install docs; strict resolution shipped in npm 7.