To find out why a package is in your build, trace the chain of dependencies from your project to it. If your SBOM keeps the dependency graph, read the path there. Otherwise use your package manager: npm explain for Node projects, or the Maven dependency tree goal for Java.
The question behind the question
Someone sees a package name in an SBOM or scan result and asks who put it there. Usually nobody chose it. It arrived because something you did choose depends on something that depends on it. Knowing the chain matters because it decides your fix: you cannot simply upgrade a package that you never declared.
Method 1: read the SBOM graph
CycloneDX and SPDX can both record relationships between components. If your SBOM includes them, find the suspect component, then walk back to the root component. Each hop is a dependency edge. If the SBOM is a flat list with no relationships, you can see that the package exists, not why.
That is one reason to prefer an SBOM that keeps the graph. Our post on keeping the dependency graph or just a flat list covers the trade off.
Method 2: ask the package manager
For npm, the explain command (alias why) prints the chain of dependencies causing a given package to be installed in the current project. The npm docs also note it helps when you need to work out why a dependency is duplicated to satisfy conflicting version requirements.
For Maven, the dependency tree goal prints the resolved tree. Its verbose option includes omitted nodes, which helps when a version was dropped in favour of another.
npm explain some-package
mvn dependency:tree -Dverbose
Reading the answer
| What you see | What it means | Likely action |
|---|---|---|
| Declared in your own manifest | You chose it | Upgrade or remove it yourself |
| One parent, which you declared | Comes with that parent | Upgrade the parent, or override the child |
| Several parents with different ranges | Version conflict | Align ranges or accept duplicates |
| Only dev or test paths | Not in the shipped build | Lower priority, but confirm scope |
What to record
When you finish the trace, write down the chain in the ticket. Include the parent package, the version range it asks for, and whether the component ships to production. The next person who sees the same name will not start over.
Also check that the SBOM matches reality. If the package manager shows no path and the SBOM lists it, the SBOM may describe a different build, a stale lockfile, or a container layer. See why your SBOM is missing components for the reverse problem.
Try it yourself
Click through it at your own pace, or open it full screen. Find a transitive component and look at which direct dependency it belongs to.
Safeguard's dependency scanning and SBOM views show transitive components alongside direct ones, and you can try the free scan on your own repository.
Quick check
Can I trace a package from a flat SBOM list?
Not reliably. A flat list shows that a component exists. You need the relationships, or your package manager, to see why.
Does a dev only path matter?
It matters less for what you ship, but confirm the scope, because build tools can still be attacked.
Sources
- npm docs, npm explain
- Apache Maven Dependency Plugin, dependency:tree
- CycloneDX, Software Bill of Materials capabilities
Last reviewed: 19 October 2026.