Since npm 7, npm refuses to install when packages' peer dependency requirements conflict — one package wants React 17, another demands React 18, and npm won't guess. ERESOLVE is npm protecting the tree from a combination its own rules say is invalid. The error output includes a plain-English report of exactly which packages are fighting.
The lines under ERESOLVE name the conflict precisely: “While resolving: your-app”, “Found: react@…”, “Could not resolve dependency: peer react@… from …”. Two packages and two version ranges — that's the entire dispute. npm also writes the full report to a file it names in the error (eresolve-report.txt in the npm cache logs folder).
--legacy-peer-deps knowingly: npm install --legacy-peer-deps restores npm 6 behaviour (peers warned about, not enforced). Legitimate when the conflicting package works fine in practice and no updated release exists — common with older project templates. It is a documented mode, not a hack, but it means you own verifying the combination actually runs.--force is the blunter sibling — it installs despite conflicts and can leave a broken tree. Prefer legacy-peer-deps; reserve force for throwaway experiments.legacy-peer-deps=true to the project's .npmrc so every install (and CI) behaves the same — surprises belong in code review, not in CI logs.Check for a second conflict hiding behind the first — npm reports them one layer at a time. Also confirm the npm version in play (npm -v): a project built under npm 6 (which tolerated these trees) often meets ERESOLVE for the first time on a newer machine or CI image. The overrides field in package.json is the surgical last resort for pinning one transitive peer — powerful, and worth a comment in the code explaining why it exists.
Is --legacy-peer-deps dangerous? It removes a safety check, so the installed combination is unverified by npm's rules. In practice it's widely used for known-good ecosystems (older React tooling especially). The risk is real but modest; the alternative of never installing is worse.
Why did this start suddenly? A dependency released a new major version, or npm itself was upgraded. Nothing in your code changed — the negotiation between packages did.