npm / npm/cli

[BUG] npm prefers `devDependencies` to `dependencies`

Open
#6,465 6 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Bug Priority 2 Release 9.x
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

When a package is included in both dependencies and devDependencies npm install will install the devDependencies

  • npm will mark the package 'dev', commands like --omit dev will not install the package
  • npm will satisfy the edge defined by the devDependencies, not dependencies
  • this happens whether the spec's overlap or not
Expected Behavior

I expect npm to either error, or prefer the dependencies. Preferring devDependencies leads to a number of confusing behaviors

  1. Creating a production bundle with npm install --omit dev does not include one of the prod dependencies
  2. Installing the package as a dependency will install the prod dependency, which may not be the same spec the package was tested or built with
Steps To Reproduce

Create an example package in test. Add a package to dev and normal dependencies. I chose typescript arbitrarily. You can use the same spec or a different spec. The order of dependencies and devDependencies does not matter, npm always prefers devDependencies.

{
  "name": "test",
  "version": "0.0.1",
  "dependencies":{"typescript":"^5"},
  "devDependencies":{"typescript":"^4"}
}

Install dependencies and explain typescript. You should see that it installed typescript ^4 and it's a dev dependency.

$ npm install
$ npm explain typescript
typescript@4.9.5 dev
node_modules/typescript
  dev typescript@"^4" from the root project

Now let's omit dev dependencies. You should see that node_modules doesn't include any typescript.

$ npm install --omit dev
$ npm explain typescript
npm ERR! No dependencies found matching typescript

This is also a change from npm 6, where prod dependencies are preferred

$ npx -- npm@6 install
$ jq .version node_modules/typescript/package.json
"5.0.4"
$ npx -- npm@6 install --production
$ jq .version node_modules/typescript/package.json
"5.0.4"

Now lets's complete the example by demoing that npm will use the transitive prod dependency. Make a new package test2

{
  "dependencies": {
    "test": "file:../test"
  }
}

Now when we install, using install-links true to install it as a regular dependency instead of a symlink, npm uses the dependencies. Consumers thru npm will use a completely different version that doesn't satisfy the version the package was tested with.

$ npm install --install-links=true
$ npm explain typescript
typescript@5.0.4
node_modules/typescript
  typescript@"^5" from test@0.0.1
  node_modules/test
    test@"file:../test" from the root project
Environment
  • npm: 9.6.6
  • Node.js: N/A
  • OS Name: N/A
  • System Model Name: N/A
  • npm config:
; N/A

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

Start by reproducing the behavior with the test and test2 example packages using npm install, npm explain, and --omit dev; compare it with npm 6. The issue is done when overlapping dependencies either produce an error or consistently prefer the production dependency, including when the package is installed transitively.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
cli
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.