What are peer dependencies in a Node module?
By Flavio Copes
Learn what peerDependencies mean in package.json, how npm 7 and newer install them, and how packages declare compatibility with a shared host library.
A peerDependency says your package is designed to work with a compatible version of another package, usually a host library or framework. It lets a plugin use the same host package as the application instead of installing its own separate copy.
Since npm 7, peer dependencies are installed automatically by default. npm 3 through 6 did not install them automatically and only printed a warning, which is why many older explanations say the consuming project must always install them itself.
You declare peer dependencies in package.json:
{
"name": "my-react-plugin",
"peerDependencies": {
"react": "^18.0.0 || ^19.0.0"
}
}
This tells npm that the plugin is compatible with React 18 and 19. It also lets npm detect a conflict if the application uses an incompatible React version.
Dependencies, devDependencies, and peerDependencies
dependenciesare packages required when your package runs. npm installs them with your package.devDependenciesare used to develop, test, or build your package. They are not installed for people who install your package as a dependency.peerDependenciesdescribe a compatibility relationship with a package that should be shared with the consuming project.
A React component library is a common example. If it bundled its own React in dependencies, an application could end up with two React copies. Declaring React as a peer tells npm to use a compatible React from the application’s dependency tree.
The npm package.json documentation recommends using a broad compatible version range. An unnecessarily narrow range can make otherwise compatible packages impossible to install together.
What happens when versions conflict?
Suppose an application depends on React 17 while a plugin declares this:
{
"peerDependencies": {
"react": "^19.0.0"
}
}
Those ranges do not overlap. Modern npm can stop with an ERESOLVE error because it cannot build a dependency tree that satisfies both requirements.
The right fix is usually to install compatible package versions. Options such as --legacy-peer-deps can bypass peer dependency enforcement, but they can also leave you with a combination the package author did not support.
Peer ranges follow semantic versioning, just like normal dependency ranges.
How to declare an optional peer dependency
Some integrations are optional. Declare the peer normally, then mark it optional with peerDependenciesMeta:
{
"peerDependencies": {
"typescript": ">=5"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
}
npm does not automatically install optional peer dependencies. Your package must also work when that optional integration is absent.
Related posts about node: