In practice, choose CycloneDX when your SBOM program is security-driven — vulnerability correlation, VEX, attestations — and SPDX when it is license-and-legal-driven or a customer contract names ISO/IEC 5962; most organizations should generate one internally and convert on demand rather than maintain both. The formats overlap on perhaps 80% of everyday content, and the remaining 20% is where your use case decides.
Both have standards-body weight now. SPDX 2.2 (later 2.3) is ISO/IEC 5962:2021. CycloneDX 1.6 was ratified as ECMA-424 in 2024. Both satisfy the NTIA minimum elements, both are accepted under Executive Order 14028 procurement language, and the EU Cyber Resilience Act names neither exclusively. Anyone telling you one format is "the compliant one" is selling something.
Where the specs actually differ
| Dimension | CycloneDX (1.6+) | SPDX (2.3 / 3.0) |
|---|---|---|
| Origin | OWASP, security tooling community | Linux Foundation, license compliance community |
| Standardization | ECMA-424 | ISO/IEC 5962:2021 (2.3); SPDX 3.0 published 2024 |
| Serializations | JSON, XML, protobuf | JSON, YAML, RDF/XML, tag-value, spreadsheet |
| License expression depth | SPDX license IDs, basic expressions | Full SPDX expression language, LicenseRef- custom licenses, file-level and snippet-level findings |
| Vulnerability/VEX | Native (vulnerabilities array, CDX VEX, VDR) | External — OpenVEX or CSAF alongside |
| Beyond software | SaaSBOM, HBOM, ML-BOM/AI-BOM, CBOM (crypto) | SPDX 3.0 profiles: security, licensing, AI, dataset, build |
| Identity | purl-first, plus CPE and SWID | External refs (purl, CPE) via externalRefs |
| Signing | Native (JSF, XML-DSIG) or external | External (sigstore/cosign attestation) |
Two of those rows drive most real decisions. First, purl-first identity: security tools match vulnerabilities by package URL, and CycloneDX puts purl front and center, while in SPDX 2.x it lives in an optional externalRefs block that generators sometimes omit — and an SBOM without purls is nearly useless for vulnerability correlation. Second, license granularity: SPDX can express "this file, lines 100-140, is LGPL-2.1-only inside an Apache-2.0 package," which M&A due-diligence lawyers care about and no security tool has ever asked for.
Tooling parity, tested
The good news: mainstream generators emit both. syft packages dir:. -o cyclonedx-json and -o spdx-json are equally one flag. Trivy, cdxgen (CycloneDX-native), and the SPDX tools cover the rest. In our experience the differences show up downstream:
- Consumers: Dependency-Track (the most deployed open-source SBOM analysis platform) is CycloneDX-native and converts SPDX on ingest, with occasional fidelity loss in relationships. OSS Review Toolkit and FOSSA lean SPDX for license work.
- Conversion: round-tripping loses data at the edges — SPDX relationship types are richer (
STATIC_LINK,BUILD_TOOL_OF, 40+ types) than CycloneDX's dependency graph, while CycloneDX services, compositions, and VEX have no SPDX 2.x home. Convert once, in one direction, at a defined boundary. - Validation: run
cyclonedx validateorpyspdxtoolsin CI. A depressing fraction of vendor-supplied SBOMs fail their own format's schema; don't be that vendor.
Platforms that manage SBOMs at portfolio scale — SBOM Studio included — ingest both formats and normalize internally, which takes the sting out of receiving whatever your suppliers happen to send.
VEX is the sleeper issue
An SBOM says what you ship; a VEX says which published CVEs in it actually affect you. Without VEX, every SBOM you hand a customer generates a spreadsheet of "please confirm you are not affected by CVE-XXXX" emails — ask anyone who lived through Log4Shell customer-response season.
CycloneDX treats exploitability as a first-class citizen: the same schema carries analysis state (not_affected, exploitable, with justification codes) either embedded or as a standalone CDX VEX document. SPDX 2.3 has no native equivalent, so SPDX shops pair it with OpenVEX or CSAF — perfectly workable, but now you maintain document linkage across two specs. SPDX 3.0's security profile closes much of this gap on paper; consumer-tool support is still catching up to the spec. If VEX is central to your customer story, CycloneDX is the shorter path today. For the mechanics, see how to read a CycloneDX SBOM.
A decision rule that survives contact
- Security engineering owns the SBOM program → CycloneDX internally. Vulnerability correlation, VEX, and signing workflows are native, and Dependency-Track-class tooling just works.
- Legal/OSPO owns it → SPDX. File- and snippet-level license findings,
LicenseRef-custom licenses, and the ISO number on contracts. - A customer or regulator names a format → send them that format, generated by conversion from your internal standard at release time. Never hand-maintain two sources of truth; they will drift by the second release.
- You produce AI/ML systems → look hard at both CycloneDX ML-BOM and SPDX 3.0's AI profile before committing; this corner of both specs is still moving.
The honest summary: this is a two-standard world for the foreseeable future, interop is imperfect but manageable, and the cost of picking the "wrong" internal format is a conversion step — not a rewrite.
Frequently asked questions
Can I just generate both formats for every release?
You can — syft emits both in one pipeline run — but publish one as authoritative and mark the other as derived. Dual-authoritative SBOMs inevitably disagree after someone patches one pipeline and not the other, and a customer will notice during an audit.
Does the US government require SPDX specifically?
No. EO 14028 and the NTIA minimum elements are format-neutral, and CISA guidance explicitly recognizes both SPDX and CycloneDX. Individual agencies or primes may name a format contractually, which is a procurement term, not a regulation.
Is SPDX 3.0 ready for production use?
The spec is published and genuinely improved — profiles, better security modeling, cleaner JSON-LD serialization — but as of this writing generator and consumer support trails SPDX 2.3 significantly. Emit 2.3 for interop, track 3.0 tooling quarterly, and avoid being the first production user of any parser.
Which format produces smaller SBOMs?
CycloneDX JSON is usually the most compact for the same component set; SPDX tag-value and RDF carry more structural overhead. In practice both compress to within noise of each other, and size only matters once you store tens of thousands of SBOMs — at which point storage design matters more than format.