What does npm install --legacy-peer-deps do exactly?
When is it recommended to use?
_________________________________________________________________________________________
TL;DR:
You may have this issue 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, that can be eventually fixed with the run of npm audit fix.
_______________________________________________________________________________________
What's a potential use case?
Why there could be a benefit or even a need to use this command
As a developer there are case in where you have to work on projects starting from framework or libraries that you haven’t made or developed yourself, unfortunately some of them especially in the npm world are sometimes left not update or in order to work with their dependencies last versions.
This situation can arise both in meanwhile doing personal projects or even projects that have a production version.
Especially in the node world this can lead many times in loose many hours in order to try to indeed startup those project or even integrate a library or more then one that where indeed left behind in order to work with new version of other which API are behind changed and are not anymore compatible with dependencies.
I am quite sure you may have faced such similar situation and didn’t understood the strange situation.
Basically I am will simpfy with a more graphical approch with a React Native approach, a case I had last years when running an old tutorial:
Project Alpha(e.g React Native application ), that it can’t compile and throw many errors.
Basically what could have happened is:
dependecy 1 that is compatible (it’s API are compatible with Project Alpha) depends of other:
a, b, c
Let’s say b, c( but can be many more, and more level deeper) are not been update, this can be the case of for example function signature, or class constructors have changed.
So on this situation you should KNOW and update those single dependencies manually.
Unfortunately it can be that an update version of those b, c dependecies do now exist at all.
So here it comes in rescue this command. In particular here how it behaves:
--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, actually it is telling NPM to DO NOT install latest version of dependencies, 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.
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.)
Ad exampl, in React ecosystem 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.
Or as it really saved my life, when I recompiled a React Native App that I was not update since many months.
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.)
Correlated commands
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).
In general once taking a package.json from a project that does not have Semantic Versioning due the fact that NPM do install latest version of X library on the registry, if dependencies of such are not compatible with your local one then intergration error as mentioned above are occurring.
For about this I recommend to check my other article that mention a better way of doing CI in NPM ecosystem, as a basic would always be better run NPM install CI vs NPM Install.
Audit fix
It can be as happened as you didn’t know how to use this command, you have already run npm install and have many errors message regarding dependencies, in this case do not get frustrutared and try to run the following:
npm audit fix
is not only "upgrading" but sometimes also downgrading in order to install the stable version that fix the issue, sometimes those issues comes in newer versions that maybe have introduced bugs or simply do not match with previous package's API etc.
E.g in my case for example npm install have upgrade react-script to 5.0.0 that has some issue and after have run:
npm audit fix --force
The force flag does : To address all issues (including breaking changes), run: npm audit fix --force
it installed the 3.0.1 with following message:
npm WARN audit Updating react-scripts to 3.0.1,which is a SemVer major change.
So it does the upgrade to the stable version of that package that fix the issue.