Uh oh!
There was an error while loading. Please reload this page.
fix(arborist): do not install inert optional extraneous shared dependencies - #9221
Conversation
A shared dependency of two or more umet optional dependencies, where no other package in the tree also depends on that shared package, does not need to be installed. This removes packages currently marked as extraneous from trees where some platform-specific packages share a dependency.
wraithgar
commented
Apr 14, 2026
The big "breaking change" to make sure we are aware of here is that the package lock is not altered in these cases. The package-lock still needs these listed, even if they are not reified. I don't think this introduces that breaking change but it is something we want to check for. |
lovell
commented
Apr 14, 2026
Thank you for looking at this Gar.
The lockfiles generated when installing |
Uh oh!
There was an error while loading. Please reload this page.
…encies (#9221) A shared dependency of two or more umet optional dependencies, where no other package in the tree also depends on that shared package, does not need to be installed. This removes packages currently marked as extraneous from trees where one or more failed-optional (platform-specific) packages share a transitive dependency, with `@emnapi/runtime` being a good example of this. Before: ``` $ node /path/to/cli/bin/npm-cli.js install sharp@0.35.0-rc.2 added 9 packages in 325ms $ npm ls --all ├─┬ @emnapi/runtime@1.9.2 extraneous │ └── tslib@2.8.1 deduped ├─┬ @img/sharp-wasm32@0.35.0-rc.2 extraneous │ └── @emnapi/runtime@1.9.2 deduped ├─┬ sharp@0.35.0-rc.2 │ ├── @img/colour@1.1.0 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-darwin-arm64@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-darwin-x64@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-freebsd-wasm32@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-darwin-arm64@1.3.0-rc.4 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-darwin-x64@1.3.0-rc.4 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-arm@1.3.0-rc.4 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-arm64@1.3.0-rc.4 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-ppc64@1.3.0-rc.4 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-riscv64@1.3.0-rc.4 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-s390x@1.3.0-rc.4 │ ├── @img/sharp-libvips-linux-x64@1.3.0-rc.4 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linuxmusl-arm64@1.3.0-rc.4 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linuxmusl-x64@1.3.0-rc.4 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-arm@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-arm64@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-ppc64@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-riscv64@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-s390x@0.35.0-rc.2 │ ├─┬ @img/sharp-linux-x64@0.35.0-rc.2 │ │ └── @img/sharp-libvips-linux-x64@1.3.0-rc.4 deduped │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linuxmusl-arm64@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linuxmusl-x64@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-webcontainers-wasm32@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-win32-arm64@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-win32-ia32@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-win32-x64@0.35.0-rc.2 │ ├── detect-libc@2.1.2 │ └── semver@7.7.4 └── tslib@2.8.1 extraneous $ du -s node_modules/ 28824 node_modules/ ``` After: ``` $ node /path/to/cli/bin/npm-cli.js install sharp@0.35.0-rc.2 added 6 packages in 1s $ npm ls --all └─┬ sharp@0.35.0-rc.2 ├── @img/colour@1.1.0 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-darwin-arm64@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-darwin-x64@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-freebsd-wasm32@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-darwin-arm64@1.3.0-rc.4 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-darwin-x64@1.3.0-rc.4 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-arm@1.3.0-rc.4 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-arm64@1.3.0-rc.4 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-ppc64@1.3.0-rc.4 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-riscv64@1.3.0-rc.4 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-s390x@1.3.0-rc.4 ├── @img/sharp-libvips-linux-x64@1.3.0-rc.4 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linuxmusl-arm64@1.3.0-rc.4 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linuxmusl-x64@1.3.0-rc.4 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-arm@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-arm64@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-ppc64@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-riscv64@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-s390x@0.35.0-rc.2 ├─┬ @img/sharp-linux-x64@0.35.0-rc.2 │ └── @img/sharp-libvips-linux-x64@1.3.0-rc.4 deduped ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linuxmusl-arm64@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linuxmusl-x64@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-webcontainers-wasm32@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-win32-arm64@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-win32-ia32@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-win32-x64@0.35.0-rc.2 ├── detect-libc@2.1.2 └── semver@7.7.4 $ du -s node_modules/ 18336 node_modules/ ``` ## References Fixes#8832 (cherry picked from commit 1d058b0)
This usually means the cherry-pick had conflicts. Please create a manual backport: git fetch origin release/v11
git checkout -b backport/v11/9221 origin/release/v11
git cherry-pick -x 1d058b0cc7161fa728cba2020a265a81e0ec7cdf
# resolve any conflicts, then:
git push origin backport/v11/9221Error details |
…encies (#9221) A shared dependency of two or more umet optional dependencies, where no other package in the tree also depends on that shared package, does not need to be installed. This removes packages currently marked as extraneous from trees where one or more failed-optional (platform-specific) packages share a transitive dependency, with `@emnapi/runtime` being a good example of this. Before: ``` $ node /path/to/cli/bin/npm-cli.js install sharp@0.35.0-rc.2 added 9 packages in 325ms $ npm ls --all ├─┬ @emnapi/runtime@1.9.2 extraneous │ └── tslib@2.8.1 deduped ├─┬ @img/sharp-wasm32@0.35.0-rc.2 extraneous │ └── @emnapi/runtime@1.9.2 deduped ├─┬ sharp@0.35.0-rc.2 │ ├── @img/colour@1.1.0 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-darwin-arm64@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-darwin-x64@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-freebsd-wasm32@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-darwin-arm64@1.3.0-rc.4 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-darwin-x64@1.3.0-rc.4 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-arm@1.3.0-rc.4 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-arm64@1.3.0-rc.4 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-ppc64@1.3.0-rc.4 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-riscv64@1.3.0-rc.4 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-s390x@1.3.0-rc.4 │ ├── @img/sharp-libvips-linux-x64@1.3.0-rc.4 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linuxmusl-arm64@1.3.0-rc.4 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linuxmusl-x64@1.3.0-rc.4 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-arm@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-arm64@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-ppc64@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-riscv64@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-s390x@0.35.0-rc.2 │ ├─┬ @img/sharp-linux-x64@0.35.0-rc.2 │ │ └── @img/sharp-libvips-linux-x64@1.3.0-rc.4 deduped │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linuxmusl-arm64@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linuxmusl-x64@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-webcontainers-wasm32@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-win32-arm64@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-win32-ia32@0.35.0-rc.2 │ ├── UNMET OPTIONAL DEPENDENCY @img/sharp-win32-x64@0.35.0-rc.2 │ ├── detect-libc@2.1.2 │ └── semver@7.7.4 └── tslib@2.8.1 extraneous $ du -s node_modules/ 28824 node_modules/ ``` After: ``` $ node /path/to/cli/bin/npm-cli.js install sharp@0.35.0-rc.2 added 6 packages in 1s $ npm ls --all └─┬ sharp@0.35.0-rc.2 ├── @img/colour@1.1.0 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-darwin-arm64@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-darwin-x64@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-freebsd-wasm32@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-darwin-arm64@1.3.0-rc.4 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-darwin-x64@1.3.0-rc.4 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-arm@1.3.0-rc.4 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-arm64@1.3.0-rc.4 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-ppc64@1.3.0-rc.4 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-riscv64@1.3.0-rc.4 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linux-s390x@1.3.0-rc.4 ├── @img/sharp-libvips-linux-x64@1.3.0-rc.4 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linuxmusl-arm64@1.3.0-rc.4 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-libvips-linuxmusl-x64@1.3.0-rc.4 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-arm@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-arm64@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-ppc64@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-riscv64@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linux-s390x@0.35.0-rc.2 ├─┬ @img/sharp-linux-x64@0.35.0-rc.2 │ └── @img/sharp-libvips-linux-x64@1.3.0-rc.4 deduped ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linuxmusl-arm64@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-linuxmusl-x64@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-webcontainers-wasm32@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-win32-arm64@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-win32-ia32@0.35.0-rc.2 ├── UNMET OPTIONAL DEPENDENCY @img/sharp-win32-x64@0.35.0-rc.2 ├── detect-libc@2.1.2 └── semver@7.7.4 $ du -s node_modules/ 18336 node_modules/ ``` ## References Fixes#8832
Versions of npm between 11.6.2 and 11.12.1 inclusive contained a bug that resulted in inert optional extraneous shared dependencies being installed where they were not required. npm/cli#9221 It looks like the Packagephobia-reported installation size of [sharp 0.35.0](https://packagephobia.com/result?p=sharp%400.35.0) was affected by this. --------- Co-authored-by: Steven <steven@ceriously.com>
A shared dependency of two or more umet optional dependencies, where no other package in the tree also depends on that shared package, does not need to be installed.
This removes packages currently marked as extraneous from trees where one or more failed-optional (platform-specific) packages share a transitive dependency, with
@emnapi/runtimebeing a good example of this.Before:
After:
References
Fixes#8832