Run npm explain followed by a package name. It prints the chain of dependencies that causes that package to be installed, from the package back to your root project. The alias is npm why. Use it when an advisory names a package you never chose, to find which parent to upgrade.
What the output tells you
According to the npm documentation, npm explain prints the chain of dependencies that causes a given package to be installed in the current project. You can pass one or more package specs, and only matching packages are explained. You can also pass a folder path inside node_modules to explain one specific copy, which helps when a package is duplicated to satisfy conflicting version ranges.
The docs show an example where one copy of a package is marked as a dev dependency, required by one tool, which is required by another, which the root project depends on. Reading from the bottom of that chain up gives you the direct dependency that owns the problem.
Why it matters for security
Most vulnerable packages in a JavaScript project are transitive. You did not add them, so you cannot simply bump them. The useful questions are:
- Which direct dependency brings it in?
- Is the path through a dev dependency or a production one?
- Is more than one copy installed, and are all of them affected?
- Would upgrading the parent remove it, or do you need an override?
npm explain answers the first three in one command.
A repeatable triage routine
- Get the package name and affected version from your scanner or advisory.
- Run the explain command with that name. If several versions are installed, pass the path of each copy under node_modules.
- Note the top-level parent in each chain.
- Check whether that parent has a release that updates the child. If so, upgrade the parent.
- If not, pin the child with an override, as in how to pin a transitive dependency with npm overrides.
- Re-run the explain command and your scan to confirm the old copy is gone.
| You want to know | Use |
|---|---|
| Why is this package here? | npm explain |
| What is the whole tree? | npm ls |
| Which scanner finding is reachable? | Reachability analysis |
Try it yourself
Click through it at your own pace, or open it full screen.
Pick a component and look for whether it is direct or transitive. That is the same question npm explain answers locally.
Quick check
What is the alias for npm explain?
The alias is why, so npm why works the same way.
Can I explain one specific duplicated copy?
Yes. Pass a folder path inside node_modules and npm explains that copy.
Safeguard's dependency scanning and SBOM show direct and transitive components, and reachability analysis helps you decide which findings need action first. Try the free scan at gold.safeguard.sh/scan.
Sources
Last reviewed: 19 October 2026.