Peer Dependency Version Ranges — Best Practices
How to specify peer dependency version ranges for npm packages. Learn broad ranges with || for framework compatibility and avoiding conflicts.
Detailed Explanation
Peer Dependency Version Ranges
Peer dependencies declare that your package is compatible with a specific version of another package, without bundling it. Getting the range right is critical for library authors.
What Are Peer Dependencies?
When you write a React component library, you do not want to bundle React itself. Instead, you declare it as a peer dependency:
{
"peerDependencies": {
"react": "^18.0.0"
}
}
This means "I work with React 18.x — the consumer must provide it."
Range Strategies
1. Single Major (Conservative)
"react": "^18.0.0"
Safe, but forces consumers to be on React 18.
2. Multiple Majors (Broad Compatibility)
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
Supports multiple React versions — more work to maintain but wider adoption.
3. Minimum Version Only
"react": ">=16.8.0"
Very permissive. Risky if future React versions break your library.
Best Practices
| Practice | Why |
|---|---|
Use || for multiple majors |
Maximizes compatibility |
Specify minimum minor (e.g., ^16.8.0) |
Ensures hooks support |
| Test all ranges in CI | Do not claim untested compatibility |
| Document supported versions | Help consumers choose |
| Do not use exact versions | Creates resolution conflicts |
The Diamond Problem
If package A requires react: ^17.0.0 and package B requires react: ^18.0.0, npm cannot resolve both unless they share a compatible range. This is why broad peer dependency ranges are important for library authors.
Auto-Install Behavior
npm 7+ auto-installs peer dependencies. If a conflict occurs, you will see a warning:
npm WARN Could not resolve peer dependency react@"^17.0.0"
peerDependenciesMeta
Mark optional peer dependencies:
{
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
}
}
}
Use Case
Library authors publishing npm packages that depend on frameworks like React, Vue, or Angular, needing to specify which versions of the framework are compatible.