High-performance DDEX XML builder and parser with native bindings for TypeScript/JavaScript and Python. Built on a single Rust core for consistent behavior across all platforms.
DDEX Suite brings together powerful tools for music industry data exchange, combining the robust ddex-parser
library for reading and transforming DDEX messages with the ddex-builder
library for deterministic XML generation, creating a complete round-trip solution for DDEX processing.
Working with DDEX XML shouldn't feel like archaeology. The suite transforms complex DDEX messages into clean, strongly-typed data structures that are as easy to work with as JSON.
- Single Rust Core: One implementation to rule them all - consistent behavior across JavaScript, Python, and Rust
- Dual Model Architecture: Choose between faithful graph representation or developer-friendly flattened view
- Production Ready: Built-in XXE protection, memory-bounded streaming, and comprehensive security hardening
- Deterministic Output: Consistent, reproducible XML generation with smart normalization
I'm building DDEX Suite as a rigorous, end-to-end learning project to deepen my Rust skills while unifying my JavaScript and Python experience into a production-grade toolkit for music metadata. The intent is to ship a single Rust core that serves both a high-performance, security-hardened DDEX XML parser library (ddex-parser
) and a consistent, deterministic builder library (ddex-builder
). This core is exposed through napi-rs for Node/TypeScript and PyO3 for Python, showcasing not just cross-language API design but also deep ecosystem integration, including a declarative DataFrame mapping DSL for Python users. The project is deliberately "industry-shaped," tackling the complementary challenges of transforming complex DDEX XML into clean models (parsing) and generating canonical, reproducible XML from those models. This is achieved through a dual graph+flattened data model for developer UX and an uncompromising approach to determinism, centered on a custom canonicalization specification, DB-C14N/1.0, and a stable, content-addressable ID generation engine.
Beyond the core implementation, this is a showcase of software craftsmanship and platform thinking. The suite provides consistent APIs, painless installation via prebuilt binaries, a hardened CI/CD pipeline, and robust supply-chain safety (SBOM, cargo-deny
, and Sigstore artifact signing). Every feature reflects production wisdomβfrom the parser's XXE protection to the builder's versioned partner presets system with safety locks. Paired with my validator work (DDEX Workbench), DDEX Suite delivers a credible, end-to-end Parse β Modify β Build processing pipeline, complete with enterprise-grade features like preflight validation, a semantic diff engine, and a comprehensive CLI. It illustrates how to design interoperable components that are fast, safe, and easy to adopt in real-world systems.
Latest Release: Suite v0.4.1 π
Current Development Phase: 4.4 - Streaming Parser
Target Release: Suite v1.0.0 in Q1 2026
All packages published across npm, PyPI, and crates.io! β
Package | npm | PyPI | crates.io | Version |
---|---|---|---|---|
ddex-core | - | - | β Published | v0.4.1 |
ddex-parser | β Published | β Published | β Published | v0.4.1 |
ddex-builder | β Published | β Published | β Published | v0.4.1 |
β
Phase 1-3: Complete - Core foundation, parser, and builder are fully implemented
β
Phase 4.1: Integration Testing - Round-trip functionality validated with 94 tests passing
β
crates.io Publishing - NEW! All Rust crates published to the official registry
β
Phase 4.2: Documentation - Docusaurus site in React
β
Phase 4.3: Smart Normalization Engine - Round-trip, deterministic output
β
Phase 4.3.5: Core Stabilization - Stability and performance upgrades
β
Phase 4.4: Streaming Parser - High-performance XML parser
For detailed development progress and technical implementation details, see blueprint.md.
The suite provides two complementary views of the same data with full round-trip data integrity:
Preserves the exact DDEX structure with references and extensions - perfect for compliance and round-trip operations:
interface ERNMessage {
messageHeader: MessageHeader;
parties: Party[]; // All parties with IDs
resources: Resource[]; // Audio, video, image resources
releases: Release[]; // Release metadata with references
deals: Deal[]; // Commercial terms
extensions?: Map<string, XmlFragment>; // Preserved for round-trip
toBuildRequest(): BuildRequest; // Convert to builder input
}
Denormalized and resolved for easy consumption - ideal for applications while maintaining round-trip capability:
interface ParsedRelease {
releaseId: string;
title: string;
displayArtist: string;
tracks: ParsedTrack[]; // Fully resolved with resources merged
coverArt?: ParsedImage;
_graph?: Release; // Reference to original for full data integrity
extensions?: Map<string, XmlFragment>; // Extensions preserved
}
The DDEX Suite provides powerful normalization capabilities that transform inconsistent, messy DDEX files into clean, compliant output.
Real-world DDEX files come from many sources with varying quality:
- Different namespace conventions (ern:Title vs Title vs ns2:Title)
- Inconsistent element ordering
- Mixed DDEX versions and dialects
- Redundant whitespace and formatting issues
- Non-standard extensions and attributes
DDEX Builder solves this by:
- Normalizing all input to clean DDEX 4.3 structure
- Standardizing element and attribute ordering
- Optimizing output for compliance and size
- Preserving all semantic data and business information
// Build DDEX
const { DdexBuilder } = require('ddex-builder');
const builder = new DdexBuilder();
builder.applyPreset('audio_album'); // Apply baseline preset
// Configuration options
builder.setConfig({
canonical: true, // Consistent, deterministic output
validate: true, // Ensure DDEX compliance
version: '4.3', // Target DDEX version
optimize_size: true // Remove redundant whitespace
});
// Parse messy vendor DDEX β Output clean DDEX
const { DdexParser } = require('ddex-parser');
const parser = new DdexParser();
const parsed = await parser.parse(messyVendorFile);
const cleanDdex = await builder.build(parsed);
// Result: Beautiful, compliant DDEX 4.3
Input Chaos | Output Order |
---|---|
Mixed namespace prefixes | Consistent DDEX namespaces |
Random element ordering | Specification-compliant order |
Whitespace soup | Clean, minimal formatting |
Legacy DDEX versions | Modern DDEX 4.3 |
Vendor-specific quirks | Standard-compliant structure |
The DDEX Suite ensures your business data is always preserved:
All business-critical data (ISRCs, titles, artists, deals) is preserved with 100% accuracy.
Building the same data always produces identical output - perfect for testing and validation.
Partner extensions (Spotify, Apple, YouTube) are preserved and properly namespaced.
Parse β Modify β Build workflows maintain all your data, with beneficial normalization applied.
- β‘ SIMD-Accelerated: FastStreamingParser using memchr for 25-30 MB/s production throughput
- π― Peak Performance: 500-700 MB/s for uniform XML, up to 1,265 MB/s in optimal conditions
- πΎ Memory Efficient: 90% reduction - 100MB files with <50MB peak memory (O(1) streaming)
- π Selective Parsing: 11-12x faster with XPath-like selectors for targeted extraction
- βοΈ Parallel Processing: 6.25x speedup on 8 cores with 78% efficiency
- π Cross-Language: Native streaming in Rust, Python (16M+ elements/sec), Node.js (100K elements/sec)
- π Production Ready: 96.3% score across all validation metrics
- π§Ή Clean Output: Transform messy vendor DDEX into compliant DDEX 4.3
- π Consistent Structure: Standardized element ordering and namespaces
- β¨ Optimized Size: Remove redundant whitespace and formatting
- π Data Preservation: 100% semantic accuracy maintained
- π― Deterministic: Same input always produces same output
- π Production-Ready Python: Native PyO3 bindings with full DataFrame integration
- π DataFrame Support: Three schema options (flat, releases, tracks) for pandas integration
- β‘ Native Performance: <50ms parsing for 10MB files with Python
- π Round-Trip Python: Complete Parse β DataFrame β Build workflow support
-
π PyPI Available: Install with
pip install ddex-parser ddex-builder
- π Round-Trip Workflow: Parse β Modify β Build with 100% data preservation
- π Dual Model Architecture: Graph (faithful) and flattened (developer-friendly) views
- π‘οΈ Enterprise Security: XXE protection, entity expansion limits, memory bounds
- β‘ High Performance: Sub-millisecond processing for typical files
- π Multi-Platform: Native bindings for Node.js, Python, WASM, and Rust
- π Reference Linking: Automatic relationship resolution between entities
- π Stable Hash IDs: Content-based deterministic ID generation
- β¨ Multi-Version Support: ERN 3.8.2, 4.2, and 4.3 with automatic detection
- Streaming: Handle massive catalogs with backpressure and progress callbacks
- Semantic Diff: Track changes between DDEX message versions
- Additional Bindings: C#/.NET and Go language bindings
# JavaScript/TypeScript
npm install ddex-parser # β
Latest: v0.4.0
npm install ddex-builder # β
Latest: v0.4.0
# Python
pip install ddex-parser # β
Latest: v0.4.0
pip install ddex-builder # β
Latest: v0.4.0
# Rust
cargo add ddex-core # β
Latest: v0.4.0
cargo add ddex-parser # β
Latest: v0.4.0
cargo add ddex-builder # β
Latest: v0.4.0
<script type="module">
import init, { DdexParser, DdexBuilder } from '@ddex/wasm';
await init();
const parser = new DdexParser();
const builder = new DdexBuilder();
</script>
Bundle sizes (v0.4.0):
- Parser: 37KB (gzipped: ~12KB)
- Builder: 420KB (gzipped: ~140KB)
// Parse DDEX
const { DdexParser } = require('ddex-parser');
const parser = new DdexParser();
const result = await parser.parse(xmlContent);
// Modify the parsed data
result.flat.releases[0].title = "Updated Title";
// Build DDEX
const { DdexBuilder } = require('ddex-builder');
const builder = new DdexBuilder();
builder.applyPreset('audio_album'); // optional
const xml = await builder.build(result.toBuildRequest());
// Round-trip with beneficial normalization
const reparsed = await parser.parse(xml);
assert.deepEqual(reparsed.graph, result.graph); // β
Identical
from ddex_parser import DdexParser
from ddex_builder import DdexBuilder
import pandas as pd
# Parse DDEX message with native performance
parser = DdexParser()
message = parser.parse(xml_content)
# Export to DataFrame for analysis (NEW!)
df = message.to_dataframe(schema='releases') # 'flat', 'releases', or 'tracks'
print(f"Found {len(df)} releases")
# Modify DataFrame data
df.loc[0, 'title'] = 'Updated Album Title'
# Build from DataFrame (Round-trip support)
builder = DdexBuilder()
xml = builder.from_dataframe(df, version='4.3')
# Traditional object-based building also supported
xml = builder.build({
'header': {
'message_sender': {'party_name': [{'text': 'My Label'}]},
'message_recipient': {'party_name': [{'text': 'YouTube'}]}
},
'version': '4.3',
'releases': [{
'release_id': '1234567890123',
'title': [{'text': 'Amazing Album'}],
'display_artist': 'Great Artist',
'tracks': [
{'position': 1, 'isrc': 'USXYZ2600001', 'title': 'Track 1', 'duration': 180}
]
}]
})
use ddex_parser::DdexParser;
use ddex_builder::DdexBuilder;
// Parse DDEX message
let parser = DdexParser::new();
let result = parser.parse(&xml_content)?;
// Modify the parsed data
let mut build_request = result.to_build_request();
build_request.releases[0].title = "Updated Title".to_string();
// Build deterministic XML
let builder = DdexBuilder::new();
let xml = builder.build(&build_request)?;
// Round-trip with beneficial normalization and type safety
let reparsed = parser.parse(&xml)?;
assert_eq!(reparsed.graph, result.graph); // β
Identical
Built as a monorepo with shared core components:
βββββββββββββββββββββββββββββββββββββββββ
β DDEX Suite β
βββββββββββββββββββ¬ββββββββββββββββββββββ€
β DDEX Parser β DDEX Builder β
β Read & Parse β Generate & Build β
βββββββββββββββββββ΄ββββββββββββββββββββββ€
β Shared Core β
β Models β Errors β FFI β Utils β
βββββββββββββββββββββββββββββββββββββββββ€
β Language Bindings β
β napi-rs β PyO3 β WASM β CLI β
βββββββββββββββββββββββββββββββββββββββββ
- XXE (XML External Entity) protection
- Entity expansion limits (billion laughs protection)
- Deep nesting protection
- Size and timeout limits
- Memory-bounded streaming
- Supply chain security with cargo-deny and SBOM
Operation | Performance | Memory | Notes |
---|---|---|---|
Production Files | 25-30 MB/s | <50MB | Complex DDEX files with varied content |
Uniform XML | 500-700 MB/s | <50MB | Repetitive patterns, SIMD sweet spot |
Peak Throughput | 1,265 MB/s | <50MB | Optimal conditions, cached data |
100MB File | ~3.6s | <10MB | 90% memory reduction achieved |
1GB File | ~36s | <50MB | Maintains constant memory |
Selective Parsing | 11-12x faster | <5MB | Extract specific elements only |
Parallel (8 cores) | 6.25x speedup | ~6MB/thread | 78% efficiency |
Language | Throughput | Memory | Async Support | Notes |
---|---|---|---|---|
Rust | 50K elem/ms | Native | Yes (tokio) | Baseline |
Python | 16M elem/s | <100MB | Yes (asyncio) | PyO3 native |
Node.js | 100K elem/s | <100MB | Yes (streams) | Native streams + backpressure |
WASM | 10K elem/s | Browser | Yes (Promise) | 37KB bundle size |
File Size | Parse Time | Memory Usage | Mode | Notes |
---|---|---|---|---|
10KB | <5ms | <2MB | DOM | Single release |
100KB | <10ms | <5MB | DOM | Small catalog |
1MB | <50ms | <20MB | DOM | Medium catalog |
10MB | <400ms | <100MB | Auto | Threshold for streaming |
100MB | <3.6s | <10MB | Stream | 90% memory reduction |
1GB | <36s | <50MB | Stream | Constant memory usage |
Component | Size | Target | Status |
---|---|---|---|
Rust Core | 9.4MB | - | β Development artifact |
Node.js (npm) | 347KB | <1MB | β Excellent |
Python wheel | 235KB | <1MB | β Compact |
WASM bundle | 114KB | <500KB | β 77% under target! |
crates.io β NEW! | |||
ddex-core | 57.2KiB (34 files) | <10MB | β Compact |
ddex-parser | 197.9KiB (43 files) | <10MB | β Efficient |
ddex-builder | 1.1MiB (81 files) | <10MB | β Under limit |
- Blueprint - Detailed architecture, roadmap, and technical implementation
- Parser API - Parser documentation
- Builder API - Builder documentation
- Round-Trip Guide - Parse β Modify β Build guide
- Error Handbook - Understanding and handling errors
- ddex-core - Core data models and utilities
- ddex-parser - Parser API reference
- ddex-builder - Builder API reference
- Contributing Guide - Development setup and guidelines
- API Changelog - Version history and breaking changes
This project is in active development. While external contributions aren't yet accepted, we welcome feedback and issue reports. Follow the project for updates!
MIT License - see LICENSE file for details.
DDEX Suite is designed to complement DDEX Workbench by providing structural parsing and deterministic generation while Workbench handles XSD validation and business rules.
Repository: https://github.com/daddykev/ddex-suite
Status: Phase 4.4 - Additional Bindings
Parser: v0.4.1 on npm and PyPI
Builder: v0.4.1 on npm and PyPI
Suite Target: v1.0.0 in Q1 2026
Last Updated: September 15, 2025