Skip to content

[BUG] npm link <path> --workspace=<ws> ignores the workspace: dep is attached to the root (and --save writes the root manifest) #9590

Description

@manzoorwanijk

Is there an existing issue for this?

  • I have searched the existing issues

This issue exists in the latest npm version

  • I am using the latest npm

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions