Skip to content

[BUG] Auto install of transitive optional peer if also specified as dev #7772

Closed
@Akatuoro

Description

@Akatuoro

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

Having a package (peer) both as transitive peerOptional dependency and as dev dependency leads to it being installed for production as well.

Scenario:

optional-peer-test@0.0.1
├─┬ direct@1.0.0 (dependency)
│ └── peer@1.0.0 (peerOptional dependency)
└── peer@1.0.0   (dev dependency)
$ npm i --omit=dev

$ npm explain peer
peer@1.0.0
node_modules/peer
  dev peer@"file:../deps/peer/peer-1.0.0.tgz" from the root project
  peerOptional peer@"file:../peer/peer-1.0.0.tgz" from direct@1.0.0
  node_modules/direct
    direct@"file:../deps/direct/direct-1.0.0.tgz" from the root project

Expected Behavior

The peerOptional dependency is not auto installed for npm i --omit=dev.

Steps To Reproduce

Reproduction repo: https://github.com/Akatuoro/optional-peer-test

For a real world scenario, use the package.json

{
    "name": "optional-peer-test",
    "version": "0.0.1",
    "description": "Testing npm behavior for installing optional peer dependencies",
    "scripts": {
        "test": "npm i --omit=dev && npm ls @sap/hana-client",
        "clean": "rm -Rdf node_modules && rm package-lock.json"
    },
    "dependencies": {
        "@sap/hdi": "4.5.2"
    },
    "devDependencies": {
        "@sap/hana-client": "2.21.31"
    }
}

and run

npm i --omit=dev

resulting in

$ npm ls @sap/hana-client
optional-peer-test@0.0.1
├── @sap/hana-client@2.21.31
└─┬ @sap/hdi@4.5.2
  └── @sap/hana-client@2.21.31 deduped

$ npm explain @sap/hana-client
@sap/hana-client@2.21.31
node_modules/@sap/hana-client
  dev @sap/hana-client@"2.21.31" from the root project
  peerOptional @sap/hana-client@"^2 >= 2.5" from @sap/hdi@4.5.2
  node_modules/@sap/hdi
    @sap/hdi@"4.5.2" from the root project

Also note that in the package-lock.json, the @sap/hana-client is now marked as devOptional, while it was never included under optionalDependencies. When a npm-shrinkwrap.json is then generated and the package is published, the consumer also auto installs the peerOptional dependency.

This seems to be due to arborist not really differentiating between optional dependencies and optional peer dependencies, as e.g. discussed here: #4859 (comment) .

Environment

  • npm: 10.8.3
  • Node.js: v22.7.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    Bugthing that needs fixingNeeds Triageneeds review for next steps

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions