feat: add dedupePeers option to reduce peer dependency duplication#11071
Merged
Conversation
When enabled, this option applies two optimizations to peer dependency resolution: 1. Version-only peer suffixes: Uses name@version instead of full dep paths (including nested peer suffixes) when building peer identity hashes. This eliminates deeply nested suffixes like (foo@1.0.0(bar@2.0.0)). 2. Transitive peer pruning: Only directly declared peer dependencies are included in a package's suffix. Transitive peers from children are not propagated upward, preventing combinatorial explosion while maintaining correct node_modules layout. The option is scoped per-project: each workspace project defines a peer resolution environment, and all packages within that project's tree share that environment. Projects with different peer versions correctly produce different instances. Closes #11070
…r lockfile write The frozen install path (used by approve-builds) calls getOutdatedLockfileSetting but was missing the dedupePeers parameter. This caused a false LOCKFILE_CONFIG_MISMATCH error because the lockfile had the key written (as undefined/null via YAML serialization) while the check function received undefined for the config value. Fix: pass dedupePeers to the settings check call, and use spread syntax to only write the dedupePeers key to lockfile settings when it's truthy (avoiding undefined keys).
Write the value directly instead of spread syntax, and use the same != null guard pattern as autoInstallPeers in the settings checker.
When dedupePeers is false (default), don't write it to lockfile settings. This avoids adding a new key to every lockfile.
Instead of pruning transitive peers entirely (which prevented per-project differentiation), keep them but use version-only identifiers. This way: - Packages like abc-grand-parent still get a peer suffix when different projects provide different peer versions (correct per-project isolation) - But the suffixes use name@version instead of full dep paths, eliminating the nested parentheses that cause combinatorial explosion
lajczi
approved these changes
Mar 23, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces an opt-in dedupePeers setting to reduce peer dependency duplication by changing how peer suffixes are computed (using version-only peer identifiers instead of full dep paths), and wires the option through the installer/resolver and lockfile settings.
Changes:
- Added
dedupePeersto config/workspace state, installer options, and lockfile settings so it can be persisted and checked for lockfile mismatch. - Updated peer resolution to build peer suffixes from version-only peer IDs (
name@version) to avoid nested peer suffixes. - Added resolver + installer tests covering version-only suffixes and multi-project isolation behavior.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| workspace/state/src/types.ts | Adds dedupePeers to the persisted workspace-state settings key list. |
| lockfile/types/src/index.ts | Extends LockfileSettings with dedupePeers. |
| lockfile/settings-checker/src/getOutdatedLockfileSetting.ts | Adds lockfile-outdated detection for settings.dedupePeers. |
| installing/deps-resolver/src/resolvePeers.ts | Implements version-only peer IDs via peerNodeIdToPeerId() and passes dedupePeers through context. |
| installing/deps-resolver/src/index.ts | Plumbs dedupePeers into the resolver entrypoint options. |
| installing/deps-resolver/test/resolvePeers.ts | Adds unit tests for dedupePeers peer suffix behavior. |
| installing/deps-installer/src/install/extendInstallOptions.ts | Adds dedupePeers to strict install options and defaults it to false. |
| installing/deps-installer/src/install/index.ts | Persists dedupePeers into lockfile settings and includes it in outdated-setting checks; passes option into dependency resolution. |
| installing/deps-installer/src/getPeerDependencyIssues.ts | Adds dedupePeers to options typing for peer-issues collection. |
| installing/deps-installer/test/install/peerDependencies.ts | Adds integration tests asserting version-only suffixes in lockfile snapshots and workspace isolation. |
| installing/commands/src/recursive.ts | Allows recursive command options to include dedupePeers. |
| installing/commands/src/installDeps.ts | Allows installDeps command options to include dedupePeers. |
| installing/commands/src/install.ts | Allows install command options to include dedupePeers. |
| config/reader/src/Config.ts | Adds dedupePeers?: boolean to the Config interface. |
| .changeset/dedupe-peers-option.md | Documents the new dedupePeers feature for release notes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Awesome work, Zoltan! |
- Register dedupe-peers in config schema, types, and defaults so .npmrc/pnpm-workspace.yaml settings are parsed correctly - Use Boolean() comparison in settings checker so enabling dedupePeers on a pre-existing lockfile triggers re-resolution - Fix changeset text and test names: transitive peers are still propagated, just with version-only IDs (no nested dep paths)
3 tasks
|
Amazing! |
zkochan
added a commit
that referenced
this pull request
Mar 24, 2026
…11079) When enabled, peer dependency suffixes use version-only identifiers (name@version) instead of full dep paths, eliminating nested suffixes like (foo@1.0.0(bar@2.0.0)). Transitive peers are still tracked but identified by version instead of full dep path. Backport of #11071 to v10. Closes #11070
This was referenced Mar 30, 2026
|
Am I overlooking something or isn't this included in the docs yet? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
dedupePeerssetting that reduces peer dependency duplicationname@version) instead of full dep paths when building peer suffixes(@emotion/react@11(react@18))→(@emotion/react@11.0.0)autoInstallPeersCloses #11070
Before/After
Nested peer suffixes eliminated:
Multi-project correctness preserved:
Test plan