Safeguard
Developer Tools•

How do I see why a package is in my dependency tree?

Use npm ls to print the tree and npm explain to see why a package is included. A first-week guide to tracing unfamiliar dependencies back to their parent.

Safeguard Security Team
3 min read

Run npm ls with the all option to print the full tree, and npm explain with a package name to see why that package is included. In Maven, print the dependency tree instead. The goal is the path from your direct dependency down to the package you are asking about.

What the commands show

The npm documentation says npm ls prints all installed package versions to stdout in a tree structure, and includes their dependencies when the all option is specified. By default it shows only immediate dependencies, since depth defaults to 1 unless all is set. Positional arguments in name and version-range form limit the output to the paths to the named packages. The same page notes that to get a bottoms-up view of why a given package is in the tree at all, you use npm explain.

For Maven, the dependency mechanism page describes how transitive dependencies are pulled in automatically and how the nearest definition decides versions. Printing the tree there uses the Maven dependency plugin, whose output shows which parent brings in an artifact. See how Maven picks a version.

A tracing routine

  1. Start from the name in the alert or scan result.
  2. Run npm explain with that name. Read the chain from the package up to your direct dependency.
  3. Run npm ls with the package name to see every path and every installed version.
  4. Identify the direct dependency at the top of each chain. That is the one you can change.
  5. Check whether a newer version of that parent drops or updates the child.

Reading the result

What you seeWhat it means
One pathUpdate that parent, or replace it
Several pathsSeveral parents bring it in; fix them all or pin the child
Multiple versionsDifferent parents want different versions; check each
Dev-only pathAffects developer machines and CI more than production

Why this matters for new developers

Most dependencies in a modern project are transitive. If you cannot trace one, you cannot fix it. The skill is also the base for judging an alert: a deep dev-only chain is a different conversation from a production direct dependency. See direct versus transitive vulnerabilities.

Make it visual

A printed tree gets long fast. An inventory view that lists every package, direct or not, with its parent, is easier to scan. The demo below shows one.

Where Safeguard fits

Safeguard can do the inventory and watching for you. Its SBOM and dependency scanning lists what a repository actually pulls in, reachability analysis helps separate reachable findings from noise, and policies can gate a pull request. You can try a free scan on a repository to see the output.

Try it yourself

Click through it at your own pace, or open it full screen. Look at how each package shows its depth and the parent that introduced it.

Quick check

Why does npm ls show so few packages by default?

Depth defaults to 1 unless the all option is set, so it lists only immediate dependencies.

Does npm explain change anything?

No. It only reports why a package is present.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.