Understanding peer dependencies in JavaScript
In the package.json file, we can see a few fields dedicated to dependencies. One of them which is often not fully understandable is peer dependency.
It may happen someday, that you will be developing your package. In this situation, there will be users installing your packages in their projects.
Your package has its dependencies, but what if user adds the same dependency but in a different version? Their behaviors might be incompatible. To prevent your users from using wrong versions you can use peer dependency and block installation when packages are incompatible.
Let’s explain it on the react-dom package which can be added to your package. It has both “normal” dependencies and peerDependencie defined so it is good to highlight differences between them.
[email protected] used in the examples has the following dependencies in the package.json:
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.21.0"
},
"peerDependencies": {
"react": "^18.0.0"
},Case #1 (“normal” dependencies)
I created simple package my-package with following “normal” dependencies:
"dependencies": {
"react-dom": "18.1.0",
"loose-envify": "1.0.0"
}react-dom “want” to install [email protected] (current highest compatible with loose-envify@^1.1.0)
my-package “want” to install [email protected]
I installed my-package with npm install, then verified dependencies tree with npm list --depth=1 and this is the output I got:
my-package@1.0.0
├─┬ loose-envify@1.0.0
│ └── js-tokens@1.0.3
└─┬ react-dom@18.1.0
├── loose-envify@1.4.0
├── react@18.2.0
└── scheduler@0.22.0Both my-package and react-dom have their own versions of loose-envify— but their behavior is incompatible. If we are sure that it won’t affect our package behavior we can stay with this solution.
Case #2 (peer dependencies with failure)
Instead of loose-envify, my-package is now using react package (peer dependency to react-dom) and it has the following dependencies:
"dependencies": {
"react-dom": "18.1.0"
"react": "18.0.0",
}react-dom “want” to install [email protected] (current highest compatible with react@^18.0.0)
my-package “want” to install [email protected].
[email protected] is incompatible with the [email protected].
As a result, any attempt to install it with an incompatible react version ([email protected] or [email protected]) will end with failure:
npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR!
npm ERR! While resolving: react-dom@18.2.0
npm ERR! Found: react@18.0.0
npm ERR! node_modules/react
npm ERR! react@"18.0.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^18.2.0" from react-dom@18.2.0
npm ERR! node_modules/react-dom
npm ERR! react-dom@"18.2.0" from the root project
npm ERR!
npm ERR! Conflicting peer dependency: react@18.2.0
npm ERR! node_modules/react
npm ERR! peer react@"^18.2.0" from react-dom@18.2.0
npm ERR! node_modules/react-dom
npm ERR! react-dom@"18.2.0" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.