pnpm handles peer dependencies more strictly and correctly, which is one of its important features.
What are Peer Dependencies:
json// react-dom/package.json { "peerDependencies": { "react": "^18.0.0" // Requires host project to provide react } }
npm/Yarn Issues:
bash# Project dependencies { "dependencies": { "react": "^17.0.0", "react-dom": "^18.0.0" # Needs react 18 } } # npm/Yarn may install silently, causing version mismatch # Problems only discovered at runtime
pnpm's Strict Handling:
bash# Error during installation pnpm install # ERR_PNPM_PEER_DEP_ISSUES Unmet peer dependencies # react-dom@18.0.0 requires react@^18.0.0 but you have react@17.0.0
Solutions:
- Install Correct Matching Version
bashpnpm add react@18 react-dom@18
- Use pnpm.overrides
json// package.json { "pnpm": { "overrides": { "react": "^18.0.0" } } }
- Ignore peer dependency (not recommended)
json{ "pnpm": { "peerDependenciesMeta": { "react": { "optional": true } } } }
Correct Usage of peerDependencies:
json// Plugin package's package.json { "name": "my-react-plugin", "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" }, "peerDependenciesMeta": { "react-dom": { "optional": true // Optional peer dependency } } }
Handling in Monorepo:
yaml# pnpm-workspace.yaml packages: - 'packages/*' # packages/plugin/package.json { "peerDependencies": { "react": "^18.0.0" } } # packages/app/package.json { "dependencies": { "react": "^18.0.0", "@my-org/plugin": "workspace:*" } } # pnpm automatically provides react from app to plugin
Auto-install peer dependencies:
toml# .npmrc auto-install-peers=true # Auto install peer dependencies strict-peer-dependencies=false # Non-strict checking
Comparison Summary:
| Feature | npm/Yarn | pnpm |
|---|---|---|
| Check Timing | May delay to runtime | Check immediately at install |
| Error Messages | May be unclear | Clear error messages |
| Version Conflicts | May silently ignore | Strict error reporting |
| Monorepo Support | Average | Excellent |