Why use peer dependencies instead of regular after npm 7?

30 Views Asked by At

Suppose we have the following situation. You are working on cool-app and depend on react and cool-package:

"dependencies": {
  "react": "^16.0.0",
  "cool-package": "^1.0.0"
}

You are unfortunately still on React 16 instead of 18. cool-package on the other hand has a peer dependency of React 18:

"peerDependencies": {
  "react": "^18.0.0",
}

In npm versions 4, 5 and 6, if you try to npm install in cool-app, you will get a warning about an unmet peer dependency. This is because cool-app doesn't provide a version of react that meets the version requirements of ^18.0.0.

If cool-package instead had a regular dependency (not a peer dependency) on react with a version requirement of ^18.0.0, when you npm install in cool-app, a second version of react will be downloaded since the v16 of React that cool-app has can't meet the ^18.0.0 requirement of cool-package.

However, in npm v7 (and every version since (1, 2)), the behavior of peer dependencies has changed. If the peer dependency hasn't been met, instead of displaying a warning when you npm install, it will instead install the missing dependency, just like it would have done if regular dependencies were used instead of peer dependencies.

So in our example with cool-app, if we're using npm 7, cool-app will have two different versions of React: v16 and v18 even though cool-library uses a peer dependency.

Given this, I am unclear about what the differences are between regular and peer dependencies, and on how important these differences are in practice.

Context: This is the conversation that lead to me having these questions.

1

There are 1 best solutions below

0
Adam Jenkins On BEST ANSWER

If the peer dependency hasn't been met, instead of displaying a warning when you npm install, it will instead install the missing dependency,

This isn't what is says here:

In previous versions of npm (4-6), peer dependencies conflicts presented a warning that versions were not compatible, but would still install dependencies without an error. npm 7 will block installations if an upstream dependency conflict is present that cannot be automatically resolved

And it's what I've experienced. If you have a dependency in your package.json whose version is unable to reconcile with a peerDependency of the dependency you're installing, it doesn't install that peerDependency, instead it fails to install the dependency, which is a much better behaviour, IMO.

So in our example with cool-app, if we're using npm 7, cool-app will have two different versions of React: v16 and v18 even though cool-library uses a peer dependency.

This is incorrect. If cool-app has react ^16 installed and you try to install cool-package that has a dependency on react ^18 - it fails - it's an unresolvable conflict.

In the answer you referenced you'll note the same:

in version 7 peerDependencies are automatically installed unless an upstream dependency conflict is present that cannot be automatically resolved