bomly explain

Last updated July 30, 2026View source (v0.21.0)

Answer "why is this package here?" — trace every dependency path that pulls a package into the graph. explain runs the same detect and match stages as scan, then walks the graph from the project roots to the package you named.

Minimal invocation

bomly explain send

On a project that depends on express:

ecosystem  npm
manager    npm
package    send@0.18.0
scope      runtime
direct     no
licenses
  MIT [declared]
introduced by:
  demo@1.0.0
  └─ express@4.19.2
     ├─ send@0.18.0 [analyzed] (transitive)
     └─ serve-static@1.15.0
        └─ send@0.18.0 [analyzed] (transitive)

Every path is shown, not just the shortest one — here send enters both directly through express and again through serve-static, which matters when you're deciding what to bump.

Naming the package

Pass a package name or a full PURL. A PURL disambiguates when the same name exists in more than one ecosystem:

bomly explain lodash
bomly explain pkg:npm/react
bomly explain github.com/spf13/cobra --path ./backend

Targets and gates

explain accepts the same target flags as scan (--path, --recursive, --url/--ref, --image, --sbom) and the same pipeline gates. Add --enrich to include the package's vulnerabilities in the explanation, and --audit/--analyze when you want policy findings or reachability on it:

bomly explain send --enrich            # include known vulnerabilities
bomly explain send --enrich --analyze  # and whether they're reachable
bomly explain send --json              # structured paths for tooling

The JSON shape is documented in the explain schema.

Exit codes

Same table as every command — see Exit Codes. Notably 5 when the target has no supported manifests, and 4 for a malformed PURL.

See also

  • scan — the shared target, gate, and output flags
  • diff — when the question is "what changed" rather than "why is it here"
  • Interactive TUI — explore the same paths interactively with bomly scan --interactive