| Crates.io | vex2pdf |
| lib.rs | vex2pdf |
| version | 3.0.0 |
| created_at | 2025-04-22 16:45:55.340772+00 |
| updated_at | 2026-01-16 20:35:01.340384+00 |
| description | A tool to convert CycloneDX(VEX) JSON or XML documents to PDF reports |
| homepage | |
| repository | https://gitlab.com/jurassicLizard/vex2pdf |
| max_upload_size | |
| id | 1644334 |
| size | 5,235,591 |
A command-line tool to convert CycloneDX (VEX/VDR/(S)BoM) Documents in JSON or XML format to PDF reports.
Perfect for automated security reporting in containerized workflows, CI/CD pipelines, and production environments where reliability, speed, and minimal dependencies are critical.
VEX2PDF is a Rust application that scans the current directory for CycloneDX (VEX/VDR/(S)BoM files (JSON and XML) and converts them to human-readable PDF reports. It fully supports the CycloneDX schema version 1.5 and provides compatibility for version 1.6 documents that only use 1.5 fields. Documents using 1.6-specific fields may not process correctly. The tool handles various elements of the CycloneDX document format including vulnerabilities, components, metadata, and more.
VEX2PDF renders CycloneDX vulnerability analysis information with visual enhancements to improve readability and quick risk assessment:
The tool displays vulnerability analysis states with color-coded formatting for immediate visual recognition:
Response actions indicate what remediation steps are available or planned:
When present in the CycloneDX document, the analysis section appears after each vulnerability's description and includes:
Analysis sections only appear when the CycloneDX document includes analysis data. If no analysis information exists for a vulnerability, the section is omitted entirely.
This tool uses Liberation Sans fonts to render PDFs. The fonts are embedded directly in the binary, so no extra font configuration is required and the binary works standalone and is fully portable.
The embedded Liberation Sans fonts are licensed under the SIL Open Font License (OFL).
Use the --license flag to display full license details:
vex2pdf --license
The font license file is also available at Liberation fonts License file in the current repository.
Install VEX2PDF directly from crates.io:
cargo install vex2pdf
After installation, the vex2pdf binary will be available in your Cargo bin directory.
To use VEX2PDF as a library in your Rust project:
# Default: CLI + concurrent processing (recommended for most use cases)
cargo add vex2pdf
# Library with concurrent processing (no CLI dependencies)
cargo add vex2pdf --no-default-features --features concurrency
# Library with sequential processing (minimal dependencies)
cargo add vex2pdf --no-default-features
# CLI with sequential processing
cargo add vex2pdf --no-default-features --features cli
Feature Flags:
| Feature | Description | Default |
|---|---|---|
cli |
Command-line interface and argument parsing (requires clap, env_logger) |
✓ Yes |
concurrency |
Concurrent file processing using threadpool (requires jlizard-simple-threadpool) |
✓ Yes |
Library Usage Example:
use vex2pdf::lib_utils::config::Config;
use vex2pdf::run;
fn main() {
let config = Config::default()
.working_path("./input")
.output_dir("./output")
.max_jobs(Some(4)); // Only available with 'concurrency' feature
run(config).expect("Failed to process files");
}
For complete API documentation, visit docs.rs/vex2pdf.
Notice: As of v0.6.1 no extra font configuration is needed. Fonts have been embedded in the software binary. Check Fonts handling and license for further information
Clone the repository, then build the application with cargo build --release. The binary will be available at target/release/vex2pdf.
Users can either:
Currently, No Mac Binaries are provided however Mac Users can build and install with cargo. Please check the From Source Section
If Mac release binaries are needed please create an issue
Version 2.0.0 introduces breaking changes to improve the library architecture and provide more flexibility. Most users won't need to make any changes.
No changes required! The CLI interface remains unchanged. All default features (CLI + concurrency) are enabled by default.
No changes required! Your code will continue to work as-is.
--no-default-featuresVersion 2.0 introduces a new concurrency feature that's enabled by default. If you're using --no-default-features, you now have two options:
Option 1: Add concurrency back (recommended for most use cases)
# Update your Cargo.toml or installation command
cargo add vex2pdf --no-default-features --features concurrency
Option 2: Use sequential processing (simpler, no threading)
# No changes needed - files will now process sequentially
cargo add vex2pdf --no-default-features
PdfGenerator API directlyThe PdfGenerator struct no longer has a lifetime parameter:
Before (v1.x):
let generator: PdfGenerator<'_> = PdfGenerator::new(config);
After (v2.0):
let generator: PdfGenerator = PdfGenerator::new(config);
// Or simply let type inference handle it:
let generator = PdfGenerator::new(config);
If you were using these deprecated environment variables, switch to CLI flags:
| Removed Variable | Replacement |
|---|---|
VEX2PDF_SHOW_OSS_LICENSES=true |
vex2pdf --license |
VEX2PDF_VERSION_INFO=true |
vex2pdf --version |
concurrency feature flag allows you to choose between concurrent (faster) or sequential (simpler) processingjlizard-simple-threadpool for better maintainabilityPdfGenerator struct (deprecated since v0.9.0)For a complete list of changes, see the CHANGELOG.md.
VEX2PDF is designed for batch processing and can be run without arguments to automatically process all CycloneDX files in the current directory. As of v0.9.0, the tool also supports command-line arguments for more precise control over input files, output directories, and report customization.
Run the application in a directory containing CycloneDX (VEX/VDR/(S)BoM files (JSON or XML):
./vex2pdf
The tool will:
VEX2PDF supports command-line arguments for convenient configuration. All arguments can also be set via environment variables as shown in the Configuration section.
To see all available options, run:
vex2pdf --help
Available options:
A tool to convert CycloneDX(VEX) JSON or XML documents to PDF reports
Usage: vex2pdf [OPTIONS] [FILE_OR_FOLDER_TO_PROCESS]
Arguments:
[FILE_OR_FOLDER_TO_PROCESS] File to process (JSON or XML) or Folder containing said file types.
Please note that this tool is designed for batch processing. So If
this is not set the tool scans the current directory for all parseable
files and converts them. if a folder is set the tool scans just the
first level of the directory (non-recursive) [env: VEX2PDF_WORKING_PATH=]
Options:
-m, --show-novulns-msg <SHOW_NOVULNS_MSG>
[env: VEX2PDF_NOVULNS_MSG=] [possible values: true, false]
-t, --report-title <REPORT_TITLE>
Overrides the default title of the report [env: VEX2PDF_REPORT_TITLE=]
-n, --pdf-meta-name <PDF_META_TITLE>
Overrides the default PDF meta name [env: VEX2PDF_PDF_META_NAME=]
-b, --bom-novulns <PURE_BOM_NOVULNS>
Treats the file as a pure bill of materials and shows only the components
without the vulnerabilities [env: VEX2PDF_PURE_BOM_NOVULNS=] [possible values: true, false]
-c, --show-components <SHOW_COMPONENTS>
Controls whether the component list is shown [env: VEX2PDF_SHOW_COMPONENTS=]
[possible values: true, false]
-d, --output-dir <OUTPUT_DIR>
Sets the directory where the parser should output the files [env: VEX2PDF_OUTPUT_DIR=]
-j, --max-jobs <MAX_JOBS>
Sets the maximum number of jobs for concurrent generation tasks, when not set or set to `0`
this defaults to using the maximum available parallelism on the system which is given by
[`std::thread::available_parallelism`] [env: VEX2PDF_MAX_JOBS=]
-L, --license
Dumps the open-source software license text to the terminal and exits
-h, --help
Print help
-V, --version
Print version
Examples:
# Process a specific file
vex2pdf my-bom.json
# Process a specific directory
vex2pdf /path/to/bom/files/
# Specify output directory
vex2pdf my-bom.json -d /path/to/output/
# Hide components list
vex2pdf -c false
# Custom report title
vex2pdf -t "Security Vulnerability Assessment"
# Process with single-threaded mode (no concurrency)
vex2pdf --max-jobs 1 my-bom.json
# Process with 4 concurrent jobs
vex2pdf --max-jobs 4 /path/to/bom/files/
# Combine multiple options
vex2pdf my-bom.json -d ./reports/ -t "Q4 Security Report"
$ ./vex2pdf
[2025-10-24T18:00:00Z INFO] vex2pdf 0.9.0 - CycloneDX (VEX) to PDF Converter
[2025-10-24T18:00:00Z INFO] Copyright (c) 2025 Salem B. - MIT Or Apache 2.0 License
[2025-10-24T18:00:00Z INFO]
[2025-10-24T18:00:00Z INFO] Active font path: <embedded liberationSans fonts> -- use --license to show Font license details
[2025-10-24T18:00:00Z INFO]
[2025-10-24T18:00:00Z INFO] Using default report title
[2025-10-24T18:00:00Z INFO] Using default pdf metadata title
[2025-10-24T18:00:00Z INFO]
[2025-10-24T18:00:00Z INFO] Scanning for BoM/Vex Files in ./documents
[2025-10-24T18:00:00Z INFO] Found 2 JSON files
[2025-10-24T18:00:00Z INFO] Found 5 XML files
[2025-10-24T18:00:00Z INFO] Processing ./documents/example1.json
[2025-10-24T18:00:00Z INFO] Generating PDF: ./documents/example1.json
[2025-10-24T18:00:00Z INFO] Successfully generated PDF: ./documents/example1.pdf
[2025-10-24T18:00:00Z INFO] Processing ./documents/example2.json
[2025-10-24T18:00:00Z INFO] Generating PDF: ./documents/example2.json
[2025-10-24T18:00:00Z INFO] Successfully generated PDF: ./documents/example2.pdf
[2025-10-24T18:00:00Z INFO] Processing ./documents/example3.xml
[2025-10-24T18:00:01Z WARN]
[2025-10-24T18:00:01Z WARN] NOTE: Downgrading CycloneDX BOM from spec version 1.6 to 1.5
[2025-10-24T18:00:01Z WARN] Reason: Current implementation does not yet fully support spec version 1.6
[2025-10-24T18:00:01Z WARN] Warning: This compatibility mode only works for BOMs that don't utilize 1.6-specific fields
[2025-10-24T18:00:01Z WARN] Processing will fail if 1.6-specific fields are encountered
[2025-10-24T18:00:01Z WARN]
[2025-10-24T18:00:01Z INFO] Generating PDF: ./documents/example3.xml
[2025-10-24T18:00:01Z INFO] Successfully generated PDF: ./documents/example3.pdf
[2025-10-24T18:00:01Z INFO] Processed 7 files
See sample generated PDFs from various CycloneDX documents in the repository:
All PDFs include embedded Liberation Sans fonts and require no additional dependencies to view.
No configuration files are required. However the application has some customization options available via Environment variables.
Windows Users: To set environment variables on Windows, use:
- Command Prompt:
set VEX2PDF_ENV_VARIABLE=false && vex2pdf- PowerShell:
$env:VEX2PDF_ENV_VARIABLE="false"; vex2pdf
The following environment variables can be used to customize behavior:
| Variable | Purpose | Default |
|---|---|---|
| VEX2PDF_NOVULNS_MSG | Controls the "No Vulnerabilities reported" message display | true |
| VEX2PDF_REPORT_TITLE | Overrides the default report title | Not set (uses default title) |
| VEX2PDF_PDF_META_NAME | Overrides the PDF metadata title | Not set (uses default metadata title) |
| VEX2PDF_PURE_BOM_NOVULNS | Whether to treat the file as a component list instead of a vulnerability list | false |
| VEX2PDF_SHOW_COMPONENTS | Whether to additionally show the component list after the vulnerability list | true |
| VEX2PDF_MAX_JOBS | Controls the maximum number of concurrent processing jobs | Not set (uses max parallelism) |
This variable controls how the Vulnerabilities section appears when no vulnerabilities exist:
Example : VEX2PDF_NOVULNS_MSG=false vex2pdf
Overrides the default report title with custom text
Example : VEX2PDF_REPORT_TITLE="My Custom VEX Report" vex2pdf
Overrides the PDF metadata title with custom text
Example 1 : VEX2PDF_PDF_META_NAME="VEX Report - Company XYZ" vex2pdf
Example 2 : VEX2PDF_PDF_META_NAME="VEX Report - Company XYZ" VEX2PDF_REPORT_TITLE="My Custom VEX Report" vex2pdf
Whether to treat the file as a pure CycloneDX Bill of Materials only listing the components and ignoring the vulnerability list
Example : VEX2PDF_PURE_BOM_NOVULNS=true vex2pdf
Whether to show the complete list of components after the vulnerabilities section. The default behaviour is true but this can be overridden
Example: VEX2PDF_SHOW_COMPONENTS=false vex2pdf
Controls the maximum number of concurrent jobs for processing multiple BOM files:
0 (default): Uses all available CPU cores for maximum parallelism1: Runs in single-threaded mode (sequential processing in main thread)2-255: Uses the specified number of concurrent jobsSingle-threaded mode is useful for:
Multi-threaded mode (default) provides:
Example (single-threaded): VEX2PDF_MAX_JOBS=1 vex2pdf
Example (4 concurrent jobs): VEX2PDF_MAX_JOBS=4 vex2pdf
Example (default parallelism): VEX2PDF_MAX_JOBS=0 vex2pdf or simply vex2pdf
VEX2PDF uses structured logging to provide clear visibility into its operation. Logs include timestamps, severity levels, and module paths for easy troubleshooting.
The tool supports four log levels:
By default, the tool shows INFO level logs without any configuration. You can control the log level using the RUST_LOG environment variable:
# Default behavior (info level) - no configuration needed
vex2pdf
# Show all logs including debug information (verbose mode)
RUST_LOG=debug vex2pdf
# Show only warnings and errors (quiet mode)
RUST_LOG=warn vex2pdf
# Show only errors (minimal output)
RUST_LOG=error vex2pdf
# Disable all logging
RUST_LOG=off vex2pdf
Note: Debug logs are completely removed from release builds at compile time for optimal performance and smaller binary size.
Output Routing:
This separation allows for proper Unix-style piping and redirection:
# Capture only errors to a file
vex2pdf 2> errors.log
# Separate normal output and errors
vex2pdf > output.log 2> errors.log
For full API documentation, please visit:
To generate documentation locally:
cargo doc --open
For information about testing, code coverage, architecture, and the traits system, see Developer Notes.
The test suite includes comprehensive integration tests that validate PDF generation accuracy using BLAKE3 checksums of normalized content (with timestamps and dynamic IDs stripped).
# Run all tests (with CLI feature, default)
cargo test
# Run only library unit tests
cargo test --lib
# Run library tests without CLI dependencies
cargo test --lib --no-default-features
# Build library-only (no CLI dependencies)
cargo build --no-default-features
Note: Integration tests require the cli feature and will be skipped when testing with --no-default-features.
Warning: PDF checksums used in integration tests are generated from debug builds. While checksums should be consistent across builds, differences in compiler optimizations between debug and release modes may occasionally cause checksum mismatches. If you encounter checksum failures in release builds, this is expected behavior and does not indicate a test failure.
# Install coverage tool
cargo install cargo-llvm-cov
# Generate HTML coverage report
cargo llvm-cov --html
# Opens coverage report in browser at target/llvm-cov/html/index.html
Tests work seamlessly from both the git repository and crates.io packages.
This tool fully supports CycloneDX schema version 1.5 and provides compatibility for version 1.6 documents that only use 1.5 fields. Documents using 1.6-specific fields may not process correctly. For more information about the CycloneDX format, see:
This tool implements a special compatibility mode for CycloneDX 1.6 documents:
specVersion: "1.6", it will:
This compatibility approach works well for documents that don't use 1.6-specific fields but allows the tool to process newer documents without requiring users to manually modify them.
Limitations:
When processing 1.6 documents, you'll see console messages indicating the compatibility mode is active.
Changes to the software between version increments are documented under Changelog.md.
This project is licensed under either of:
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you shall be dual-licensed as above, without any additional terms or conditions.
This project uses third-party dependencies that may be distributed under different licenses. Please refer to the license information provided with each dependency for details.