# How to Fix the npm ERESOLVE Dependency Error in Expo

> By Lawrence Arya, Founder & CEO of VP0. Published 2026-06-27. 7 min read.
> Source: https://vp0.com/blogs/npm-eresolve-dependency-error-expo-fix

Hitting npm ERESOLVE in an Expo project means a peer dependency conflict. The reliable fix is to let Expo choose SDK-compatible versions, not to force-install past it.

**TL;DR.** The npm ERESOLVE error means npm cannot satisfy a package's peerDependencies, a tree check it has enforced since npm 7. In an Expo project the fix is almost always to install with npx expo install, or run npx expo install --fix, so Expo picks versions that match your installed SDK instead of letting npm guess. Reach for --legacy-peer-deps or --force only as a deliberate, temporary escape hatch, then pin your SDK and React versions so it stays fixed. Start the app's screens from a free VP0 design and let Claude Code or Cursor wire them.

If npm throws an ERESOLVE error in an Expo project, it is telling you it cannot satisfy a package's peer dependencies, and the reliable fix is to let Expo choose versions that match your SDK rather than forcing npm past the conflict. Run `npx expo install <package>` instead of `npm install <package>`, or run `npx expo install --fix` to realign everything to your SDK in one pass. The screens around the dependency you are adding are fastest to start from a free [VP0](/explore) design that Claude Code or Cursor reads directly, so your time goes to the fix and not the layout.

## What the ERESOLVE error is actually telling you

ERESOLVE is short for "could not resolve dependency tree." npm prints it when it tries to build a single tree where every package's declared `peerDependencies` are satisfied, and finds that two requirements contradict each other. A common shape is a library that lists React 18 as a peer while your project has resolved React 19, so there is no version of React that makes both happy.

This check is not new behavior in your project; it is new behavior in npm. Since [npm 7 the CLI installs and validates peer dependencies automatically](https://github.blog/news-insights/product-news/presenting-v7-0-0-of-the-npm-cli/), where npm 6 silently ignored them. That single change is why a project that installed cleanly a couple of years ago now stops with a wall of red text. The official [npm install documentation](https://docs.npmjs.com/cli/v10/commands/npm-install) describes the same flags people reach for, `--legacy-peer-deps` and `--force`, and is the right reference when you decide how to respond.

## Why Expo projects hit it so often

Expo is opinionated about versions on purpose. Each Expo SDK pins a matched set of packages, React, React Native, and the Expo libraries, so they are tested together as a unit. The moment you run `npm install some-library@latest`, npm fetches whatever the newest version declares, which was very likely built against a different React Native than your SDK pins, and the peer requirements collide.

The [Expo guide to installing libraries](https://docs.expo.dev/workflow/using-libraries/) is explicit that you should install with `npx expo install` rather than the raw npm command for exactly this reason: Expo looks up the version of each package that is known to work with your installed SDK and installs that, instead of the latest on the registry. If you have ever fixed a tracking or payments screen, the [Expo Stripe integration walkthrough](/blogs/ai-stripe-integration-expo-apps/) follows the same install-the-pinned-version discipline.

## The fix that holds: let Expo pick the versions

For a single new package, install it the Expo way:

```bash
npx expo install react-native-reanimated
```

When the tree is already broken, realign the whole project to your SDK in one command:

```bash
npx expo install --fix
```

`--fix` walks every Expo-managed dependency, compares the installed version against the version your SDK expects, and corrects the mismatches. After it runs, delete `node_modules` and your lockfile and reinstall so the tree is rebuilt from the corrected versions:

```bash
rm -rf node_modules package-lock.json
npx expo install --fix
```

This resolves the conflict properly, which is the difference between fixing ERESOLVE and merely hiding it.

## When --legacy-peer-deps or --force is the right call

Sometimes the conflicting package is not Expo-managed, for example a pure JavaScript utility that simply declares an old peer range. There Expo cannot pick a version for you, and an override is reasonable, as long as it is deliberate.

| Approach | What it does | Use it when |
| --- | --- | --- |
| npx expo install --fix | Sets Expo packages to SDK-correct versions | The conflict involves React, React Native, or an Expo library |
| npm install --legacy-peer-deps | Ignores peer conflicts, installs anyway (npm 6 behavior) | A non-Expo package declares an outdated peer range |
| npm install --force | Ignores peers and overwrites cache and mismatches | Last resort, when you accept and have tested the mismatch |

Prefer `--legacy-peer-deps` over `--force`: it is the narrower hammer, silencing only the peer check, while `--force` overrides far more and hides problems you will meet later. Neither one repairs the mismatch, so log why you used it.

## Keeping it from coming back

The durable fix is to stop fighting npm's resolver. Always add packages with `npx expo install`, commit your lockfile so teammates resolve the same tree, and run `npx expo-doctor` before a release to catch version drift early. When you upgrade, change the SDK first with `npx expo install expo@latest` and let `--fix` pull the rest into line, rather than bumping individual packages by hand. A clean starting point helps too: the [best Expo boilerplate choices for 2026](/blogs/best-boilerplate-for-react-native-expo-2026/) already ship with a coherent, SDK-aligned set of versions. If an AI builder generated your project and left mismatched versions, the [fix for Expo Router export errors from Bolt](/blogs/bolt-new-react-router-expo-mobile-fix/) covers the same realign-to-the-SDK move.

## What to choose

When ERESOLVE stops an Expo install, do not start with `--force`. Install the Expo way with `npx expo install`, and when the tree is already tangled run `npx expo install --fix`, then wipe `node_modules` and the lockfile and reinstall. Keep `--legacy-peer-deps` for the narrow case of a non-Expo package with a stale peer range, and avoid `--force` unless you have tested the mismatch and accept it. Pin versions through the SDK, commit your lockfile, and run expo-doctor so the error does not return. For the UI itself, start the screens from a free, $0 VP0 design and let Claude Code or Cursor build them while you keep the dependency tree clean.

## Frequently asked questions

### How do I fix the npm ERESOLVE error in an Expo project?

Install with npx expo install <package> instead of npm install <package>, so Expo picks a version that matches your SDK. If your tree is already broken, run npx expo install --fix to realign every Expo-managed package in one pass, then reinstall. Only fall back to npm install --legacy-peer-deps if a non-Expo package still conflicts, and treat that as temporary. Start the screens from a free VP0 design and let Claude Code or Cursor build them while you handle the dependency.

### What does ERESOLVE could not resolve mean?

It means npm built a dependency tree where a package's declared peerDependencies cannot all be satisfied at once, for example a library that needs React 18 while your project resolves React 19. npm has enforced this check since version 7, which is why projects that installed cleanly on npm 6 suddenly fail. The error is npm protecting you from a mismatched tree, not a bug in your code.

### Should I use --force or --legacy-peer-deps?

Prefer --legacy-peer-deps, which tells npm to ignore peer conflicts and install anyway, mirroring npm 6 behavior. --force is broader and will also overwrite cache and pull in deliberately mismatched versions, so it hides more problems. Neither fixes the underlying mismatch; they only silence the check. In Expo, reach for npx expo install --fix first, since it resolves the conflict properly instead of ignoring it.

### Why does Expo throw dependency errors more than plain React Native?

Expo ships an SDK that pins a matched set of packages, including React and React Native, to each SDK version. When you install a library version built for a different SDK, its peer requirements clash with the pinned set and npm raises ERESOLVE. That is also why npx expo install exists: it looks up the version of each package that is known to work with your SDK and installs that instead of the latest on npm.

### Can VP0 help me build the app while I sort out dependencies?

Yes. VP0 is a free iOS design library where each screen has an AI-readable source page, so you copy a link and Claude Code or Cursor builds the real screen in React Native or SwiftUI. That keeps your UI work moving while you resolve the dependency tree, and because you own the generated code, there is no extra runtime dependency added to the conflict you are already untangling.

## Frequently asked questions

### How do I fix the npm ERESOLVE error in an Expo project?

Install with npx expo install <package> instead of npm install <package>, so Expo picks a version that matches your SDK. If your tree is already broken, run npx expo install --fix to realign every Expo-managed package in one pass, then reinstall. Only fall back to npm install --legacy-peer-deps if a non-Expo package still conflicts, and treat that as temporary. Start the screens from a free VP0 design and let Claude Code or Cursor build them while you handle the dependency.

### What does ERESOLVE could not resolve mean?

It means npm built a dependency tree where a package's declared peerDependencies cannot all be satisfied at once, for example a library that needs React 18 while your project resolves React 19. npm has enforced this check since version 7, which is why projects that installed cleanly on npm 6 suddenly fail. The error is npm protecting you from a mismatched tree, not a bug in your code.

### Should I use --force or --legacy-peer-deps?

Prefer --legacy-peer-deps, which tells npm to ignore peer conflicts and install anyway, mirroring npm 6 behavior. --force is broader and will also overwrite cache and pull in deliberately mismatched versions, so it hides more problems. Neither fixes the underlying mismatch; they only silence the check. In Expo, reach for npx expo install --fix first, since it resolves the conflict properly instead of ignoring it.

### Why does Expo throw dependency errors more than plain React Native?

Expo ships an SDK that pins a matched set of packages, including React and React Native, to each SDK version. When you install a library version built for a different SDK, its peer requirements clash with the pinned set and npm raises ERESOLVE. That is also why npx expo install exists: it looks up the version of each package that is known to work with your SDK and installs that instead of the latest on npm.

### Can VP0 help me build the app while I sort out dependencies?

Yes. VP0 is a free iOS design library where each screen has an AI-readable source page, so you copy a link and Claude Code or Cursor builds the real screen in React Native or SwiftUI. That keeps your UI work moving while you resolve the dependency tree, and because you own the generated code, there is no extra runtime dependency added to the conflict you are already untangling.

---
*Published on the [VP0 Journal](https://vp0.com/blogs). Free to read, index and cite with attribution.*
