443

Just ran into this error:

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: nexttwin@0.1.0
npm ERR! Found: react@17.0.1
npm ERR! node_modules/react
npm ERR!   react@"17.0.1" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.8.0" from react-hook-mousetrap@2.0.4
npm ERR! node_modules/react-hook-mousetrap
npm ERR!   react-hook-mousetrap@"*" from the root project
npm ERR! 

The module I am trying to install seems to have a different peer dependency from what I have installed. It seems like npm changed its behaviour in this regard and now lets the install fail.

What can I do now to fix this? I don't want to downgrade my React version for this.

I know there is a flag called --legacy-peer-deps but I am not sure what exactly this does and whether it's recommended to use it / what the potential disadvantages are? I assume there is a reason npm did let the install fail.

It's just strange because I was using yarn up until very recently and everything was fine.

antonwilhelm
  • 5,768
  • 4
  • 19
  • 45
  • 21
    I just did `npm install xxxx --legacy-peer-deps`. The install worked, but I'm not sure whether it was a good idea to solve it this way, because I don't quite understand the flag, that's why I'm asking. But haven't yet found out what the flag *really* does! :( – antonwilhelm Feb 23 '21 at 23:20
  • 10
    Specifically I wonder how `--legacy-peer-deps` is different than `--force`, because my `npm` recommends using either approach: `npm ERR! Fix the upstream dependency conflict, or retry this command with --force, or --legacy-peer-deps` – Nate Anderson Nov 21 '21 at 20:51
  • 3
    @TheRedPea ever find the answer? My npm also states both are the same but now I read this I am concerned they are not – Sammaye Jun 07 '22 at 16:17
  • 1
    No @Sammaye I don't think I found the answer – Nate Anderson Jun 07 '22 at 16:55
  • @antonwilhelm could you find an answer to this cause currently I have the same error. – David.E Nov 04 '22 at 13:34
  • I had the same issue. 17.0.1 is a higher version comparing to 16.8.0. How come NPM consider this is a conflict? This does not make sense. – DBZHOU Feb 18 '23 at 01:30

7 Answers7

590

TL;DR:

You may be arriving upon this answer if you're upgrading from NPM v6 / Node v12.

  • NPM v7+ installs peerDependencies by default; this is not the case with previous versions of NPM.
  • NPM modules must name specific versions of their peerDependencies
  • If you already have a peerDependency installed, but not with a version named by the module, then NPM v7+ will throw an error
  • Adding --legacy-peer-deps ignores this new requirement, at the risk of introducing breaking changes

--legacy-peer-deps restores peerDependency installation behavior from NPM v4 thru v6

One way of thinking of this flag is that it isn't doing something new; rather it's telling NPM not to do something new, since NPM v7 now installs peerDependencies by default.

In many cases, this is leading to version conflicts, which will break the installation process.

The --legacy-peer-deps flag was introduced with v7 as a way to bypass peerDependency auto-installation; it tells NPM to ignore peer deps and proceed with the installation anyway. This is how things used to be with NPM v4 thru v6.

If you're unclear about the difference between regular deps and peer deps, here is a bit of context:

Dependencies vs peerDependencies

Dependencies: Libraries or modules that an NPM module needs in order to work in production. (Example: I recently built a pie chart mocking library that uses Chance.js to calculate random numbers within a specified range; Chance is therefore a dependency of my module.)

peerDependencies: A peer dependency is a specific version or set of versions of a third-party software library that a module is designed to work with. They're similar in concept to the relationship between a browser extension and a browser. (Example: react-redux has two quite logical peerDependencies: react and redux.)

This issue is being driven, in part, by React v17+

Due to the large number of modules that haven't specifically added React v17 (or more recently, React 18) as a peerDependency, it's now commonplace to encounter the unable to resolve dependency tree error when running npm installs within a v17 React application.

This error will fire whenever a module (or any of its own dependencies) lists a previous major version of React as a peerDependency without specifically including React v17 as well.

(Note: Similar behavior will occur with the major-version update of any other framework or library.)

How to check peerDependencies for any given module

NPM itself doesn't list peer deps on the pages of a given module. However, there is a simple workaround to check for peer deps, either before or after install. Simply run:

npm info name-of-module peerDependencies

This command will return the name of each peerDependency along with all compatible version(s).

Chris Perry
  • 6,666
  • 3
  • 11
  • 21
  • 4
    Very nice explanation! But am still confused by: "Conflicting peer dependency: @angular/platform-browser-dynamic@11.2.13" which is in my root. It apparently conflicts with "@angular/fire@6.1.4" which states a need for a compatible version of: "peer @angular/platform-browser-dynamic@"^9.0.0 || ^10.0.0 || ^11.0.0" - Why the error? These don't appear to be in conflict? – redevill May 14 '21 at 13:34
  • @redevill Can you send a CodeSandbox that reproduces the issue? I'm happy to take a look – Chris Perry May 14 '21 at 17:08
  • In another thread - I had someone else pointed out that npm 7.11.? needed to be updated, and that was the probable cause. I have not proved this, due to time constraints I pulled the --legacy flag. Will try and return when I have a moment. Thank you! – redevill May 18 '21 at 03:28
  • does this works for yarn ? I didn't see this flag in yarn's help – Nelson Teixeira Feb 25 '22 at 08:47
  • @NelsonTeixeira no, because Yarn 1.x treats peer dependencies the same way as npm 4-6, so no flag is needed – csvan Apr 08 '22 at 11:54
  • Why can't there be two versions and each dep using the peerdep version that they need? Or am I thinking wrong? – DFSFOT May 10 '22 at 11:40
  • Quick Question: So, as I dev with React 17, it makes sense to use --legacy-peer-deps flag despite the risk? – Vu TrongNghia Jun 01 '22 at 02:11
  • npm info name-of-module peerDependencies is not found in my npm, the global one is one of the latest – Carmine Tambascia Jun 06 '22 at 10:44
  • @CarmineTambascia are you replacing `name-of-module` with the actual module name? Try running `npm info react-redux peerDependencies` to see if that gets you a result. – Chris Perry Jun 06 '22 at 22:58
  • 1
    @VuTrongNghia I wouldn't recommend that approach in a production environment. – Chris Perry Jun 06 '22 at 22:59
  • @ChrisPerry definitely – Carmine Tambascia Jun 07 '22 at 05:49
  • Say I am developing module X. I’m not using React at all. But I choose to use dependency Y which _can work with_ React (ie has peerDependency React). Do I now have to list React in X’s peerDependency lust too else my install will fail? – Ed Randall Aug 13 '22 at 06:52
  • Can we consider that if it occurs for devDependencies, using --legacy-peer-deps is not a big deal ? To prevent crashes,... in production. – lbris Aug 26 '22 at 11:51
  • 6
    Shouldn't this rename to `--dont-install-peer-deps` or something similar then? – A dev Sep 22 '22 at 06:20
  • 2
    @Adev I see what you're saying. Naming in software is a challenging (and highly opionated) endeavor. I would personally favor your approach (probably with a more concise `--ignore-peer-deps`) -- either way you word it, the intent is more immediately obvious than "legacy". Selfishly, I probably wouldn't have as many votes if this were the case, but that's the only drawback I can think of :3 – Chris Perry Sep 23 '22 at 18:12
  • Please correct me if I'm wrong, but using the `--ignore-peer-deps` is only a half-side solution when manually installing packages. It fails to apply to any future rebuilds of the project when using `npm i` in new environments such as when building a new environment with continual integration, or when a new team member tries to build the project from scratch. – r Blue Apr 19 '23 at 13:41
99

Here's how I solved this problem:

First, what's happening: react-hook-mousetrap is looking for react@16.8.0, but it is not finding it. Instead it is finding @react17.0.1, which is a newer version. For some reason mousetrap doesn't like this newer version, and you are being notified (it is not a big deal, but they decided it was worth stopping your build).

One solution: forcibly install the specific version of react that mousetrap wants:

yarn add react@16.8.0

What this does is roll back your react version to a slightly older one that is compatible with mousetrap. You won't notice any difference, and in future iterations, hopefully mousetrap is updated, so this goes away.

Another solution: make a sweeping decision to not install any older version dependencies:

npm add xxxx --legacy-peer-deps

What this does is ignore old dependencies for this package. It is more comprehensive, and makes a lot of the decisions for you.

Izzi
  • 2,184
  • 1
  • 16
  • 26
  • 22
    --legacy-peer-deps does not roll back any dependencies to any version. It simply just doesn't try to install peer dependencies automatically. – Daniel Tabuenca Apr 15 '21 at 08:15
  • 1
    @dtabuenc - I've updated. Please edit, if you think this is still incorrect / misleading. Thx – Izzi Apr 19 '21 at 12:36
  • What I don't understand is that https://npm.anvaka.com/#/view/2d/react-hook-mousetrap does not show such a dependency in the first place?! – redevill May 14 '21 at 12:56
  • is there any way that we can just change version of any package and do it with npm install only? – Chanrithisak Phok Nov 16 '21 at 09:35
  • 2
    @redevill Peer dependencies are unfortunately not shown on npmjs.com, you need to look at the [`package.json` file of the library](https://github.com/olup/react-hook-mousetrap/blob/master/package.json#L30-L33) itself. – Valentin May 23 '22 at 07:26
  • what should i use instead of xxxx should it be react or the plugin – Zed Sep 16 '22 at 17:30
9

legacy-peer-deps:

  • Default: false
  • Type: Boolean

Causes npm to completely ignore peerDependencies when building a package tree, as in npm versions 3 through 6.

If a package cannot be installed because of overly strict peerDependencies that collide, it provides a way to move forward resolving the situation.

This differs from --omit=peer, in that --omit=peer will avoid unpacking peerDependencies on disk, but will still design a tree such that peerDependencies could be unpacked in a correct place.

Use of legacy-peer-deps is not recommended, as it will not enforce the peerDependencies contract that meta-dependencies may rely on.


If you want to continue using legacy-peer-deps without needing to add the flag to every command, you can configure it in your .npmrc (either at the project level or globally on your machine):

echo "legacy-peer-deps=true" >> .npmrc

npmrc:

npm gets its config settings from the command line, environment variables, and npmrc files.

The npm config command can be used to update and edit the contents of the user and global npmrc files.

JBallin
  • 8,481
  • 4
  • 46
  • 51
4

I resolved (with yarn) adding the following to package.json

"resolutions": {
    "**/react": "17.0.2",
    "**/react-dom": "17.0.2"
},
3

If you don't want to block installing older dependencies, you can make npm neglect those warnings by forcing the script you're running. --force

SafaGH
  • 49
  • 2
2

--legacy-peer-deps jumps the installation of all the peer dependencies and gives warnings about the peer deps to notice developers install them manually. When encountering the peer deps conflicts, other than --legacy-peer-deps, another choice is use --force.
The official doc of handling peer deps conflicts is this

p.s.
Correct the top answer: --legacy-peer-deps restores peerDependency installation behavior from NPM v3 thru v6, rather than v4 thru v6.

JSON Derulo
  • 9,780
  • 7
  • 39
  • 56
Linky
  • 21
  • 1
1

One other way is to downgrade your npm version to version 6

  • 3
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 16 '22 at 21:33
  • 3
    1. This has no supporting comment as to 'why' version 6 is any better, or what downgrading would do. 2. This is recommending going backwards in versions, which is not often advisable and has it's own issues. – Scala Enthusiast Oct 28 '22 at 15:15