It varies by ecosystem and by tool. One widely used open source detection project documents full graph output for some ecosystems, such as Maven, NuGet, Cargo and Go, and a flat component list for others, such as Gradle lockfiles, Poetry lockfiles, Helm and Swift. Check your own tool the same way.
What one project documents
The Component Detection project page includes a table of ecosystems. It says components are detected from many package managers and that many ecosystems produce a flat list rather than a graph. The table puts these in the scan and graph group: CocoaPods, Conda, Go (graph needs Go 1.11 or later), Ivy, Maven, npm including Yarn and pnpm, NuGet including Paket, Pip, Ruby, Rust through Cargo, and Uv. It puts these in the scanning just group: Conan, Docker Compose, Dockerfile, the .NET SDK through an MSBuild binary log, Gradle through lockfiles, Helm, Linux distributions, Poetry through lockfiles, SPDX SBOMs, Swift and Vcpkg.
The page does not define the columns precisely and does not list each detector's status, so treat this as one data point, not a ruling for all tools. Your tool may differ, and versions change.
Why the graph matters
A flat list tells you what is present. A graph tells you why. When a vulnerable library shows up, the graph shows which direct dependency pulls it in, so you know what to upgrade. Without relationships you can find the package but not the path to it.
| Question | Flat list | Graph |
|---|---|---|
| Is package X present? | Yes | Yes |
| Which direct dependency brought it in? | No | Yes |
| What is the shortest fix? | Guess | Traceable |
| Which products share it? | Yes | Yes |
How to test your own stack
- Pick a project in each ecosystem you ship.
- Generate an SBOM and open the dependency section.
- Check whether entries list what each component depends on, or the section is empty.
- For a known transitive package, try to trace the path from the root.
- Record the result in a one line table: ecosystem, graph yes or no, tool and version.
What to do about flat output
Do not treat it as failure. Use the package manager's own tree command to answer the path question when needed, store its output beside the SBOM, and mark the SBOM's depth honestly. CycloneDX compositions can state how complete the dependency information is.
Also note the opposite risk. A graph produced by guessing is worse than none. If a tool invents edges, a reader may trust a wrong path.
Ask your vendor
- Which ecosystems do you produce relationships for, today?
- How do you mark ecosystems where relationships are unknown?
- Does the output say so inside the file?
A worked example
A team ships a service built in three ecosystems: a Maven backend, a Poetry managed Python worker and a Swift mobile client. According to the detector page used as a reference, Maven is in the graph group, while Poetry through lockfiles and Swift are in the scanning solely group. Your own tool may behave differently, so the example is a way to think, not a prediction.
| Component | Ecosystem | Relationship data from the tool | Consequence |
|---|---|---|---|
| Backend | Maven | Graph | You can trace a vulnerable library to its direct parent |
| Worker | Poetry | Flat list | You find the package but must trace the path another way |
| Mobile | Swift | Flat list | Same as above |
When an advisory names a library present in all three, the response differs. For the backend, you open the graph and see that the library comes from one specific direct dependency. For the worker and the mobile client, you run the package manager's own tree command to answer the same question.
Making flat ecosystems workable
- Save the output of the package manager's tree or why command next to the SBOM.
- Name the file with the same release identifier.
- Link it from your SBOM notes, so a reader knows where to look.
- For libraries that cause repeated trouble, record the parent in a note.
- Revisit when your tool adds graph support for that ecosystem.
What to put in the file
CycloneDX has compositions, which state whether the dependency information for a component is complete, incomplete or unknown. Use them where your tool supports them. A file that says the relationships for the Swift component are unknown is more honest than one with an empty section that a reader might take as no dependencies.
Why reachability enters the story
A graph tells you how a package got in. It does not tell you whether your code uses it. Reachability analysis answers that second question, so both belong in a triage workflow. With a graph and reachability together, you can say that a vulnerable library is present, is pulled in by a named direct dependency, and is or is not called.
Testing your own tools
Create a small fixture project in each ecosystem with a known transitive dependency, for example one library that depends on another. Generate an SBOM and look for the edge. Keep the fixtures in a repository so you can rerun them whenever you upgrade the tool. A test that takes minutes will reveal changes in behavior that release notes may not mention.
Questions to ask a vendor
- For each ecosystem we use, do you produce relationships?
- Is that behavior stable, experimental or off by default?
- How is missing relationship data marked in the output?
- What happens when a lockfile and a manifest disagree?
Do not guess edges
An invented edge is worse than a missing one. If a tool fills in relationships by heuristics, ask how confident it is and whether it labels inferred edges. A wrong path sends a developer to upgrade the wrong package and delays the real fix.
Where Safeguard fits
Safeguard offers dependency scanning with reachability analysis. Try your own repo through the free scan at gold.safeguard.sh/scan and look at how paths are shown.
Try it yourself
Click through it at your own pace, or open it full screen.
Toggle the view and watch how many findings remain once paths and reachability are considered.
Quick check
Is a flat SBOM invalid?
No. It is valid but less useful for tracing a fix. State the limit to readers.
Can I rebuild the graph later?
Often yes, from the lockfile or package manager output, if you keep them with the SBOM.
What do CycloneDX compositions record?
They state how complete the information for part of the BOM is, so a reader knows if relationships are known, partial or unknown.
Sources
Last reviewed: 19 October 2026.