# Why is this package installed?

`node_modules` holds many more packages than `package.json` lists: installing express 4 alone adds more than sixty. Each package manager can print how one of them got there — which package requires it, which package requires that one, back to your project.

## npm

`npm why` is another name for `npm explain`. It prints each installed copy of the package and, under it, the package that requires it and the range it asks for, then the package that requires that one, until the chain reaches the root project:

```
$ npm why ms
ms@2.0.0
node_modules/ms
  ms@"2.0.0" from debug@2.6.9
  node_modules/debug
    debug@"2.6.9" from body-parser@1.20.8
    node_modules/body-parser
      body-parser@"~1.20.5" from express@4.22.3
      node_modules/express
        express@"^4.22.3" from the root project
    debug@"2.6.9" from express@4.22.3
    node_modules/express
      express@"^4.22.3" from the root project
…

ms@2.1.3
node_modules/send/node_modules/ms
  ms@"2.1.3" from send@0.19.2
  node_modules/send
    send@"~0.19.0" from express@4.22.3
    node_modules/express
      express@"^4.22.3" from the root project
…
```

Here `ms` is installed twice: 2.0.0 for debug, 2.1.3 for send. `--json` prints the same chains as JSON, and `--workspace <name>` only those of one workspace.

## pnpm

`pnpm why` prints a reverse tree: the package at the top, the packages that depend on it below, down to your project. `[deduped]` marks a package already shown.

```
$ pnpm why ms
ms@2.0.0
└─┬ debug@2.6.9
  ├─┬ body-parser@1.20.8
  │ └─┬ express@4.22.3
  │   └── my-app@1.0.0 (dependencies)
  ├── express@4.22.3 [deduped]
…

ms@2.1.3
└─┬ send@0.19.2
  ├─┬ express@4.22.3
  │ └── my-app@1.0.0 (dependencies)
  └─┬ serve-static@1.16.3
    └── express@4.22.3 [deduped]

Found 2 versions of ms
```

`-r` looks through every project in a workspace, `--prod` and `--dev` limit the search to one kind of dependency, and `--json` prints JSON.

## Yarn and Bun

Yarn 1 prints, for each copy, the reason it exists:

```
$ yarn why ms
…
info => Found "ms@2.0.0"
info Reasons this module exists
   - "express#debug" depends on it
   - Hoisted from "express#debug#ms"
…
info => Found "send#ms@2.1.3"
info This module exists because "express#send" depends on it.
```

Yarn 4's `yarn why ms` lists only the packages that depend on `ms` directly. With `-R` it prints every path from the project down to it:

```
$ yarn why ms -R
└─ my-app@workspace:.
   └─ express@npm:4.22.3 (via npm:4)
      ├─ body-parser@npm:1.20.8 (via npm:~1.20.5)
      │  └─ debug@npm:2.6.9 [6e765] (via npm:2.6.9 [6e765])
      │     └─ ms@npm:2.0.0 (via npm:2.0.0)
      …
      ├─ send@npm:0.19.2 (via npm:~0.19.0)
      │  ├─ debug@npm:2.6.9 [6e765] (via npm:2.6.9 [470d2])
      │  └─ ms@npm:2.1.3 (via npm:2.1.3)
      …
```

Bun has had `bun why` since 1.2.19.

## A dependency you added yourself

```
$ npm why express
express@4.22.3
node_modules/express
  express@"^4.22.3" from the root project
```

For a package in your own `package.json`, the chain is one step long: the project asks for it. pnpm ends at `my-app@1.0.0 (dependencies)`, and Yarn 1 says `This module exists because it's specified in "dependencies".` That is all a package manager can know. Why express was chosen, why it stays on 4, and what to run before moving it were never written anywhere it reads.

Pacmon keeps that beside `package.json`, in `.pacmon/DEPENDENCY-NOTES.md`, and shows it on the dependency's line:

```md
## express

HTTP API layer (SEC-1234).
Do not upgrade to v5 — the auth middleware is incompatible.

### Agent notes

- purpose: HTTP framework; serves the public REST API and the webhook receiver
- constraint: stay on ^4 — v5 changes router path matching and the session API
- verify: `vitest src/api` and the login e2e (`pnpm e2e:auth`)
```

## After npm audit

When `npm audit` reports a vulnerable package deep in the tree, `npm why` names the dependency of yours that brings it in. Moving that dependency is where its note matters: `constraint:` says what must not change, and `verify:` what to run afterwards. [Dependency notes for JavaScript](https://pacmon.dev/javascript/) covers the rest.
