Open source · Apache-2.0 · SPDX 2.x & 3.0 · CycloneDX 1.x

An SBOM viewer and reader for SPDX and CycloneDX.

Drop a release-level document plus its component SBOMs and navigate the whole supply chain as one tree: release → component → container image → package. Then check a delivery against it, file by file. Everything runs in your browser; files never leave your machine.

Click Load example in the app for a bundled four-document demo cascade.

SBOM Lens Explore view with the example cascade loaded: release, component and container-image SBOMs rendered as one tree, a package selected in the detail pane
SPDX 2.x & 3.0.x · CycloneDX 1.x: JSON & XML · CBOM CISA 2026, NTIA & BSI TR-03183-2 quality reports client-only · works offline (PWA)

Built for real-world SBOMs

Not a demo tool: SBOM Lens is built around the messy, multi-document cascades that actually come out of CI pipelines.

01

Cascading documents are first-class

SPDX links documents via ExternalDocumentRef and cross-document relationships in 2.x, import maps in 3.0.x; CycloneDX links BOMs via BOM-Link. SBOM Lens resolves those references across every file you load, by checksum first and then namespace (a BOM-Link carries no hash, so it resolves by namespace), and renders one continuous tree across document boundaries. Unresolved references become actionable placeholders: fetch by URL, drop the file, or confirm a suggested match.

02

Fast at real-world scale

Multi-megabyte documents with 6,500+ packages parse in a Web Worker; the tree and source views are virtualized; search runs against a prebuilt index with ranked results. No pagination, no jank.

03

Private by design

A static, client-only app. SBOMs are parsed locally and never uploaded. URL fetching only happens when you explicitly ask for it. Self-host it behind your own reverse proxy to reach private registries without tokens in the browser.

04

Honest about dirty data

Real SBOMs have quirks: checksum spacing variants, duplicate SPDXIDs, versions hiding in purls, unknown relationship types. The parser tolerates all of it and reports what it found as per-document diagnostics instead of refusing to load.

Answers questions, not just files

Six views over one workspace: the same search and facets everywhere.

Each document also gets a quality report: author, timestamp, namespace and relationship checks, plus per-package coverage of versions, suppliers, IDs, checksums and licenses: factual numbers, no invented score, and every report names and links the requirement source it checks against. The default preset is the NTIA minimum elements (2021); its successor, the CISA 2026 minimum elements (CISA, NSA, FBI and 16 international partners including the BSI), is a selectable builtin, honest about the fields the engine cannot read. Profiles evaluate on SPDX and CycloneDX alike, and a builtin BSI TR-03183-2 preset approximates what the German technical guideline expects, starting with the format itself: the TR accepts only SPDX 3.0.1+ or CycloneDX 1.6+, so an SPDX 2.x or CycloneDX 1.5 document fails that baseline in the report instead of rendering all-green. A growing preset catalog covers sector duties, FDA 524B cybersecurity, OpenChain Automotive and the G7 SBOM for AI minimum elements, and reads CBOMs too: crypto inventories checked against BSI TR-02102-1 parameters, the EU PQC roadmap, DORA and PCI DSS, counting what the BOM states, never issuing a security verdict. For standards scores in CI, pair it with a norm scorer like sbomqs; profiles are the custom, cascade-aware complement: your own minimum elements as a small JSON file.

Drop an OpenVEX or CSAF 2.0 advisory (the BSI exchange format) next to your SBOMs and the Inventory grows a VEX column: each package carries what the supplier communicates about known vulnerabilities: status, justification, impact and action. Both formats share one overlay and the same time rule, statements match by package URL and by CPE, the identifier BSI-CERT advisories actually use, and the findings export with the table. It is a communication channel, not a scanner: no CVE database, no version ranges: what the supplier said, mapped onto what you shipped. Every CSAF advisory also shows the clauses of BSI TR-03191 a file can show, as facts with clause numbers, and a folder of advisories opens even before any SBOM.

Check delivery turns the SBOM into an acceptance test: point SBOM Lens at the files you were actually delivered and it hashes them in the worker, comparing each to the SBOM's file checksums: match, mismatch, missing, unverifiable, or an extra the SBOM never listed. The delivered bytes never reach the UI thread. It is the SPDX-side counterpart to OCM Lens's blob-digest check.

Beyond “can I read this?”, every document is checked against the specification it claims to follow: 28 rules across SPDX 2.x, SPDX 3.0.x and CycloneDX 1.x catch what a consumer downstream would trip over, a relationship type outside the vocabulary, a digest whose length cannot match its algorithm, an identifier off its grammar, a duplicate bom-ref. These spec findings stay warnings and sit apart from parser notes, so you always know which you are looking at. License expressions are checked for grammar, never against the license list: rating licenses stays a non-goal, and for authoritative conformance verification the docs point at spdx/tools-java.

Explore

“What does this release contain?”

The cascading tree, detail pane and raw source. Expand entire subtrees with one keystroke; filter the tree in place.

Map

“How is this cascade wired?”

The document topology as a collapsible tree: documents as nodes, resolved references as edges, missing documents as dashed stubs.

Inventory

“Give me the parts list as a file.”

One sortable table across all documents, filtered by search and facet chips, exportable as CSV or JSON.

Licenses

“Which licences does this release actually name?”

Every identifier across the cascade: declared and concluded counts, on the SPDX License List, deprecated, or a LicenseRef, one click from its packages, exportable as CSV or Markdown. Identifier facts, no legal rating.

Conflicts

“Which packages ship in more than one version?”

Grouped by purl identity across the whole cascade, each occurrence one click from its place in the tree.

Diff

“What changed between these two releases?”

Added, removed and version-changed packages between two cascades, plus same-version rebuilds caught by their checksums, copyable as Markdown for release notes.

SBOM Lens VS Code extension icon

VS Code extension

The same viewer, right in your editor

“Open with SBOM Lens” on any .spdx file or a CycloneDX BOM as JSON or XML (.cdx.json, .cdx.xml, .bom.*), plus workspace scanning that finds every SBOM in your repo. Published on Open VSX and the VS Code Marketplace; a .vsix is built on every tag.

Get the extension

Quick start

Run it locally in under a minute, or self-host the static build anywhere: any web server, any base path, offline-capable. Or skip hosting altogether and link straight to a rendered SBOM: append ?url= to the app at /app/, repeatable so a whole cascade travels in one link.

Run locally node ≥ 20
git clone https://gitlab.com/everbrightit-group/sbom-lens.git
cd sbom-lens && npm ci
npm run dev      # → http://localhost:5173
Self-host with Docker ~25 MB nginx image
docker build -f deploy/Dockerfile -t sbomlens .
docker run --rm -p 8080:80 sbomlens
# → http://localhost:8080

A self-hosted instance can ship a curated catalog of SBOMs (sbomlens.catalog.json) so your team just opens the viewer and analyzes, with resolveRefs, one click loads a root document and every SBOM it references, recursively.