TL;DR:
- 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).
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! :(--legacy-peer-deps
is different than--force
, because mynpm
recommends using either approach:npm ERR! Fix the upstream dependency conflict, or retry this command with --force, or --legacy-peer-deps