Is there an existing issue for this?
This issue exists in the latest npm version
Current Behavior
npm link <path> --workspace=<ws> does not scope the operation to the target workspace. The linked dependency is attached to the root project instead of the workspace:
- With
--save (or --save-dev/--save-optional/etc.), the file: dependency is written to the root package.json, not to <ws>/package.json.
- Without
--save, the dependency is still added to the root node of the ideal tree (so it is placed/hoisted as a root dependency rather than a dependency of the workspace).
npm install <path> --workspace=<ws> --save behaves correctly — it writes the dependency to <ws>/package.json. Only npm link is affected.
This is the underlying reason --workspace appears to have no effect for npm link (see #9115).
Observed
# npm link <path> --workspace=ws-a --save
root package.json -> { "ext-pkg": "file:../ext-pkg" } # WRONG
ws-a package.json -> {} # expected the dep here
# npm install <path> --workspace=ws-a --save (for comparison)
root package.json -> {}
ws-a package.json -> { "ext-pkg": "file:../../../ext-pkg" } # correct
Expected Behavior
npm link <path> --workspace=<ws> should attach the dependency to the target workspace, identical to npm install <path> --workspace=<ws>. With --save, the file: spec should be written to <ws>/package.json, not the root manifest.
Steps To Reproduce
rm -rf /tmp/lt && mkdir -p /tmp/lt/ext-pkg /tmp/lt/mono/packages/ws-a
printf '{ "name": "ext-pkg", "version": "1.0.0" }\n' > /tmp/lt/ext-pkg/package.json
printf '{ "name": "mono", "version": "1.0.0", "workspaces": ["packages/*"] }\n' > /tmp/lt/mono/package.json
printf '{ "name": "ws-a", "version": "1.0.0" }\n' > /tmp/lt/mono/packages/ws-a/package.json
cd /tmp/lt/mono
npm link /tmp/lt/ext-pkg --workspace=ws-a --save
node -e "console.log('root:', JSON.stringify(require('./package.json').dependencies||{}))"
node -e "console.log('ws-a:', JSON.stringify(require('./packages/ws-a/package.json').dependencies||{}))"
# root: {"ext-pkg":"file:../ext-pkg"} <- BUG, should be empty
# ws-a: {} <- BUG, should contain ext-pkg
Compare with npm install (correct)
# from the same project
npm install /tmp/lt/ext-pkg --workspace=ws-a --save
# => ws-a/package.json gets the dep, root stays empty
Environment
- npm: 12.0.0-pre.1 (reproduced on
latest)
- Node.js: v24.17.0
- OS Name: macOS (Darwin 25.5.0)
Related: #9115
Is there an existing issue for this?
This issue exists in the latest npm version
Current Behavior
npm link <path> --workspace=<ws>does not scope the operation to the target workspace. The linked dependency is attached to the root project instead of the workspace:--save(or--save-dev/--save-optional/etc.), thefile:dependency is written to the rootpackage.json, not to<ws>/package.json.--save, the dependency is still added to the root node of the ideal tree (so it is placed/hoisted as a root dependency rather than a dependency of the workspace).npm install <path> --workspace=<ws> --savebehaves correctly — it writes the dependency to<ws>/package.json. Onlynpm linkis affected.This is the underlying reason
--workspaceappears to have no effect fornpm link(see #9115).Observed
Expected Behavior
npm link <path> --workspace=<ws>should attach the dependency to the target workspace, identical tonpm install <path> --workspace=<ws>. With--save, thefile:spec should be written to<ws>/package.json, not the root manifest.Steps To Reproduce
Compare with
npm install(correct)Environment
latest)Related: #9115