[BUG] `npm install --production` can delete local workspaces if they've been renamed
Nobody has claimed this yet.
- 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
bargets renamed tobaz, thennode_modules/barshould 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": trueset, 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--productionto 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
npm install --save-dev bar -w workspaces/foo- Edit
workspaces/bar/package.jsonand change thenametobaz 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/barandnode_modules/baz package-lock.jsoncontains:"workspaces/bar": { "name": "baz", "version": "1.0.0", "dev": true },npm lsreports no problems (though it does indicate it was dedup'ed)npm install --productiondeletesworkspaces/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->bazcauses the issue. Going frombaz->bardoes not; you still get two symlinks, but"dev": truewon't get set in the lockfile, so a--productioninstall 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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