# npm ERESOLVE Unable to Resolve Dependency Tree: How to Fix It

```text
npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error
npm error While resolving: my-app@1.0.0
npm error Found: react@19.2.0
npm error node_modules/react
npm error   react@"^19.0.0" from the root project
npm error
npm error Could not resolve dependency:
npm error peer react@"^16.9.0 || ^17 || ^18" from react-datepicker@6.9.0
npm error node_modules/react-datepicker
npm error   react-datepicker@"6.9.0" from the root project
```

(Older npm versions print the same thing with `npm ERR!` at the start of each line.)

This is a **peer dependency** conflict. A peer dependency is a package saying "I don't bundle React, I use yours — and yours must be one of these versions." Since npm 7, npm installs peer dependencies automatically and refuses to build a tree that breaks one. Here, your app uses React 19 and `react-datepicker@6.9.0` only promises to work with React 16.9 to 18.

## Read the error

Three lines tell you everything:

- **Found:** what you have — `react@19.2.0`, required by the root project (your `package.json`).
- **Could not resolve dependency:** the conflicting requirement — `peer react@"^16.9.0 || ^17 || ^18"`.
- **from:** who's asking — `react-datepicker@6.9.0`.

The [caret ranges](/blog/caret-vs-tilde-npm) matter: `^18` means 18.x only, so React 19 is outside it even if the library would probably work.

## Fix 1: upgrade the package that's behind (best)

Usually a newer release of the library already supports your version. Check what the latest version accepts:

```bash
npm view react-datepicker@latest peerDependencies
```

```text
{ react: '^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc', … }
```

The current major accepts React 19, so upgrading fixes it (read the changelog — a major version can change the API):

```bash
npm install react-datepicker@latest
```

No newer release? Check the library's issue tracker — peer range bumps often sit in a pull request or a prerelease (`npm view <package> dist-tags`).

## Fix 2: match the version it wants

If you just upgraded React (or ESLint, or TypeScript) and a key library hasn't caught up, staying one major version back for now is a legitimate choice:

```bash
npm install react@18 react-dom@18
```

## Fix 3: override the peer range for one package

If you've checked that the library works with your version and you just need npm to accept it, use `overrides` (npm 8.3+) in `package.json`. This is targeted: it changes the rule for one package, and the reason is written down in your repository.

```json
{
  "overrides": {
    "react-datepicker": {
      "react": "$react",
      "react-dom": "$react-dom"
    }
  }
}
```

`$react` means "whatever version my own `dependencies` ask for". Run `npm install` again; if the existing lockfile keeps the old resolution, delete `package-lock.json` and `node_modules` and reinstall.

## Fix 4: --legacy-peer-deps

```bash
npm install --legacy-peer-deps
```

This brings back npm 6 behaviour: peer dependencies are **ignored** entirely — not installed automatically, not checked. The install succeeds, and you take responsibility for providing compatible versions. To make it stick for everyone working on the project (and your CI), put it in `.npmrc`:

```text
legacy-peer-deps=true
```

It's a blunt tool: it silences every peer conflict, including future ones you'd want to know about. Prefer `overrides` when only one package is the problem.

## Fix 5: --force (last resort)

```bash
npm install --force
```

`--force` overrides the conflict and installs whatever it can, with no promise the result works together — in the worst case, two copies of a package end up in the tree. For libraries that rely on a single shared instance — React, with its hooks, is the classic case — two copies cause runtime errors such as "Invalid hook call". Use it to unblock yourself, not as the permanent fix.

## Which one to use

| Situation | Fix |
|---|---|
| A newer version of the library supports your version | Upgrade it |
| You just bumped a major version and a key library lags | Pin the previous major for now |
| You've confirmed the library works anyway | `overrides` for that package |
| Many old packages, legacy project | `--legacy-peer-deps` in `.npmrc` |
| Need an install right now, will fix properly later | `--force` |

## Why it works in CI but not locally (or the reverse)

`npm ci` installs exactly what `package-lock.json` describes. If the lockfile was generated with `--legacy-peer-deps` but CI doesn't use the flag, or the reverse, one of them fails. Put the setting in `.npmrc` and commit it so every install behaves the same.

pnpm and Yarn report most peer conflicts as warnings rather than failing the install, which is why the same project can install cleanly with them and fail with npm. The conflict is still there either way.
