npm / npm/cli

[BUG] `npm install --production` can delete local workspaces if they've been renamed

Open
#8,519 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug Priority 2
Dominant language
JavaScript
Stars
10.1k
Forks
4.7k
Avg merge
2d 2h
Merged PRs (30d)
19

Description

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

If you rename a local workspace package that's a dev dependency of another local workspace, and add it as a new dev dependency without removing the old one, this can cause lockfile/symlink cruft which can then cause --production installs to fully delete the local workspace directory.

Expected Behavior

Renaming a local workspace package should never cause --production installs to delete local workspaces. Ideally:

  • Obsolete local symlinks should be cleaned up, e.g. if bar gets renamed to baz, then node_modules/bar should get deleted.
  • Related to the above, depending on an obsolete local symlink (e.g. "dependencies": {"bar": "1.0.0"}) should cause an error.
  • Local workspaces should not have "dev": true set, even if they are dev deps of another workspace. This seems to get set when there are 2+ local symlinks for a package, and is likely what causes --production to delete things.

If any of the above are not feasible to implement, then npm ls or similar commands should alert users to these sorts of lockfile / tree inconsistencies.

Steps To Reproduce
Given

package.json

{
  "workspaces": ["workspaces/*"]
}

workspaces/foo/package.json

{
  "name": "foo",
  "version": "1.0.0",
  "private": true
}

workspaces/bar/package.json

{
  "name": "bar",
  "version": "1.0.0",
  "private": true
}
Run
  1. npm install --save-dev bar -w workspaces/foo
  2. Edit workspaces/bar/package.json and change the name to baz
  3. npm install --save-dev baz -w workspaces/foo

Alternatively, just check out this repo and run npm install which will get you to this point.

Observe
  • There are now symlinks at node_modules/bar and node_modules/baz
  • package-lock.json contains:
    "workspaces/bar": {
      "name": "baz",
      "version": "1.0.0",
      "dev": true
    },
    
  • npm ls reports no problems (though it does indicate it was dedup'ed)
  • npm install --production deletes workspaces/bar 💥
Additional Notes
  • This only happens with devDependencies
  • The lexicographical order of the old and new package names seems to matter. I.e. going from bar -> baz causes the issue. Going from baz -> bar does not; you still get two symlinks, but "dev": true won't get set in the lockfile, so a --production install won't delete the workspace.
Environment
  • npm: 11.5.2
  • Node.js: 22.14.0
  • OS Name: Mac OS Sequoia 15.6
  • System Model Name: Macbook Pro
  • npm config:
; copy and paste output from `npm config ls` here

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue using the linked repository, then inspect package.json and package-lock.json after renaming workspaces/bar to baz and adding the new dev dependency. Run npm ls and npm install --production; done means stale local symlinks or inconsistent lockfile metadata no longer cause the workspace directory to be deleted.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, nodejs
Domain
cli, devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.