fix(link): scope `npm link <path> --workspace` to the workspace, not the root (#9592)
`npm link <path> --workspace=<ws>` did not scope the operation to the target workspace. The linked dependency was attached to the root project instead, and with `--save` (or `--save-dev`/`--save-optional`/etc.) the `file:` spec was written to the root `package.json` rather than `<ws>/package.json`. `npm install <path> --workspace=<ws> --save` behaved correctly, so only `npm link` was affected. The cause is in `Link.linkInstall()` in `lib/commands/link.js`, which built the local Arborist without the `workspaces` option and passed `workspaces` only to `reify()`. Arborist decides which node receives the `add` request from `this.options.workspaces`, which is captured at construction time, not from the reify-time option. `buildIdealTree` merges reify options into a local variable and `#parseSettings` never copies `options.workspaces` into `this.options`, so the reify-time value never reached `#applyUserRequests`. With `this.options.workspaces` left empty, the `add` and the save were applied to the root node. The fix passes `workspaces: this.workspaceNames` to the local Arborist constructor, matching how `lib/commands/install.js` already does it. Physical placement is unchanged: under the default `hoisted` strategy the symlink still hoists to the root `node_modules`, identical to `npm install --workspace`. ## References <!-- List any relevant issues, pull requests, or external references --> Fixes #9590 Related #9589
M
Manzoor Wani committed
1a9ce8e3f56ec26dd283b8957119f721d8d3fe5f
Parent: 00b9f9f
Committed by GitHub <noreply@github.com>
on 6/22/2026, 4:11:33 PM