CycloneDX vs SPDX: which SBOM format to use, and when it matters
The two SBOM standards side by side — origins, what each models, tool support, regulatory acceptance under the CRA and US guidance — and a plain recommendation for container and Kubernetes teams.
StackRadar Team
· 8 min read
Two SBOM standards, both international, both accepted by every regulator that has expressed an opinion, both supported by every serious tool. The choice matters less than the volume of writing about it suggests — and yet you do have to pick one for your pipeline, and the right pick depends on what you will do with the document. This post gives the short answer first, then the reasoning.
Where each one came from
SPDX — Software Package Data Exchange — started in 2010 at the Linux Foundation to solve licence compliance: which licences apply to which files in a distribution, with enough precision to satisfy a lawyer. That heritage shows in its depth on files, snippets, licence expressions and copyright text. It became ISO/IEC 5962:2021 (for SPDX 2.2.1), and SPDX 3.0 in 2024 reorganised the model into profiles, including a security profile.
CycloneDX started in 2017 in the OWASP community, explicitly for security and supply-chain use cases. It models components, services, dependency graphs and — natively — vulnerability disclosures (VDR) and exploitability statements (VEX), along with attestations, cryptographic inventories and more in recent versions. It is published as ECMA-424, and the current version, 1.6, dates from 2024.
What each one is good at modelling
| SPDX 2.3 / 3.0 | CycloneDX 1.6 | |
|---|---|---|
| Package inventory with versions | Yes | Yes |
| Package identifiers (PURL, CPE) | Via external references | First-class fields |
| Dependency graph | Relationships (many types) | dependencies[], simple and direct |
| File-level detail, snippets | Deep | Basic |
| Licence expressions | Deep (its origin) | Adequate |
| Vulnerabilities in the document (VDR) | 3.0 security profile | Native since 1.4 |
| Exploitability statements (VEX) | Separate (OpenVEX, or 3.0) | Native |
| Services, APIs | No | Yes |
| Serialisations | Tag-value, JSON, YAML, RDF, XLS | JSON, XML, protobuf |
| Standard | ISO/IEC 5962:2021 | ECMA-424 |
For the job this site cares about — knowing which packages are in a running image so they can be matched to advisories — the deciding row is the identifier one. A vulnerability matcher works from a PURL: pkg:apk/alpine/nginx@1.27.5-r1?distro=alpine-3.21.3 carries the ecosystem, the distro and the exact version that an advisory's affected range is evaluated against. CycloneDX puts that in a required-shaped field on every component; SPDX carries it as one external reference among several. Both work; one is designed for it.
The same package in both
{
"type": "library",
"name": "nginx",
"version": "1.27.5-r1",
"purl": "pkg:apk/alpine/nginx@1.27.5-r1?arch=x86_64&distro=alpine-3.21.3",
"cpe": "cpe:2.3:a:nginx:nginx:1.27.5-r1:*:*:*:*:*:*:*",
"licenses": [{ "license": { "name": "BSD-2-Clause" } }]
}{
"SPDXID": "SPDXRef-Package-apk-nginx-3c9251e68aafb845",
"name": "nginx",
"versionInfo": "1.27.5-r1",
"downloadLocation": "NOASSERTION",
"licenseConcluded": "BSD-2-Clause",
"externalRefs": [
{ "referenceCategory": "SECURITY", "referenceType": "cpe23Type",
"referenceLocator": "cpe:2.3:a:nginx:nginx:1.27.5-r1:*:*:*:*:*:*:*" },
{ "referenceCategory": "PACKAGE-MANAGER", "referenceType": "purl",
"referenceLocator": "pkg:apk/alpine/nginx@1.27.5-r1?arch=x86_64&distro=alpine-3.21.3" }
]
}Same facts, different shapes. Syft produces either from one scan, and the CycloneDX reference has a complete real document to read alongside the fragment above.
What the regulators actually say
- EU Cyber Resilience Act. Annex I requires manufacturers to "identify and document" components including by drawing up an SBOM in a commonly used machine-readable format, covering at least top-level dependencies. No standard is named; the Commission may specify formats by implementing act. Reporting obligations apply from 11 September 2026. The CRA post goes through the detail.
- United States. NTIA's 2021 minimum elements name SPDX, CycloneDX and SWID as acceptable formats; CISA's 2025 update to the minimum elements keeps both. Executive Order 14028 procurement guidance references NTIA.
- Germany (BSI TR-03183-2) accepts both, with field-level requirements that both can meet.
The consistent pattern: regulators specify content — supplier, name, version, unique identifier, dependency relationships, author, timestamp — and let you pick the container for it. Both formats carry all of it.
Tool support in practice
Generators: Syft, Trivy, cdxgen (CycloneDX only), Docker Scout, BuildKit attestations (SPDX). Consumers: Grype, Trivy, OSV-Scanner, Dependency-Track (CycloneDX first), GUAC, and every commercial platform. In the container and Kubernetes world CycloneDX is the default output and the format most consumers are tested against; SPDX is the default in BuildKit's --sbom attestations and in distribution packaging. StackRadar generates and ingests CycloneDX 1.6, validated against the official schema; the SBOM tools comparison covers the generators.
How to decide
- Someone else specifies it. A customer contract, a procurement questionnaire, a platform you upload to. Do what they say; generate it directly rather than converting.
- Vulnerability tracking is the main use. CycloneDX. Native PURLs, a simple dependency graph, VEX in the same document when you get to it.
- Licence compliance is the main use. SPDX. File-level detail and licence expressions are what it was built for.
- Both. Emit both from the same scan. Syft does it in one command per format and the cost is one extra file per image.
Frequently asked questions
What is the difference between CycloneDX and SPDX?
Both are machine-readable SBOM standards. SPDX (Linux Foundation, ISO/IEC 5962:2021) began in 2010 as a licence-compliance format and models packages, files, snippets and their licences in depth. CycloneDX (OWASP, ECMA-424) was designed from 2017 for security: it models components with PURLs, services, dependency graphs, and carries vulnerability (VDR) and exploitability (VEX) data natively. Both can express a basic package inventory; they differ in what else they are good at.
Which SBOM format do regulators require?
Neither specifically. The EU Cyber Resilience Act requires a machine-readable SBOM in a "commonly used" format and names no standard; US federal guidance (NTIA minimum elements, CISA’s 2025 update) accepts both SPDX and CycloneDX. What both regimes care about is the content: unique identifiers, versions, supplier, dependency relationships, and timestamps.
Is CycloneDX or SPDX more common for containers?
CycloneDX, by a comfortable margin. Syft, Trivy, Grype, Docker Scout, Snyk, Dependency-Track, Trivy Operator and StackRadar all emit or consume CycloneDX by default; most also emit SPDX. SPDX is the norm in the Linux distribution and Linux Foundation ecosystems and in BuildKit’s image attestations.
Can I convert between CycloneDX and SPDX?
Yes, with some loss. Syft can output either format from the same scan, and the CycloneDX CLI and SPDX tooling can convert existing documents. Fields that exist in one model and not the other — VEX statements, SPDX snippets, annotations — do not survive a round trip. If a customer demands one format, generate it directly rather than converting.
What is SPDX 3.0?
SPDX 3.0, released in April 2024, restructured the standard into profiles — core, software, security, licensing, build, AI, dataset — with a graph-based model, and added security fields that narrow the gap with CycloneDX. Tool support is arriving gradually; most production pipelines still emit SPDX 2.3 in 2026.