zX12 is a fast and flexible X12 EDI parser written in Zig with a C-compatible API. It transforms complex X12 documents (such as healthcare claims 837P and 837I) into structured JSON format using declarative, schema-driven parsing.
The zX12 parser is designed to handle the full complexity of X12 EDI documents, including:
- Hierarchical Structures - HL (Hierarchical Level) segments with parent-child relationships
- Nested Loops - Multiple levels of nested non-hierarchical loops
- Segment Groups - Related segments (like NM1+N3+N4+REF) processed together
- Composite Elements - Extraction of sub-components from composite fields
- Repeating Patterns - Complex repeating element structures (e.g., HI segments)
- Value Mapping - Code-to-description translations defined in schema
- Flexible Output - Configurable JSON structure via schema
- Schema-Driven: JSON schemas define parsing logic, making it adaptable to different X12 transaction sets without code changes
- C-Compatible API: Simple, stable C API for integration with any language that supports FFI
- Cross-Platform: Builds on Linux, macOS (x86_64 and ARM64), and Windows
- Multiple Language Support: Includes Python bindings with pre-built wheels for multiple platforms
- Declarative Configuration: No code changes needed to support new transaction types - just update the schema
zX12/
├── src/ # Zig source code
│ ├── main.zig # C API implementation
│ └── x12_parser/ # Core parser modules
├── include/ # C header files
│ └── zx12.h # Public C API
├── python/ # Python package
│ └── zx12/ # Python module with bindings
├── schema/ # X12 schema definitions
│ ├── 837i.json # Institutional claim schema
│ ├── 837p.json # Professional claim schema
│ └── SCHEMA.md # Schema documentation
├── samples/ # Example X12 files
├── examples/ # Usage examples
│ ├── c/ # C examples
│ └── python/ # Python examples
├── docs/ # Additional documentation
├── build.zig # Zig build configuration
└── pyproject.toml # Python package configuration
- Zig Compiler: Version 0.15.0 or later (installation instructions)
- C Compiler: GCC, Clang, or MSVC (for building C examples)
- Python: 3.7+ (for Python bindings)
- UV: Astral UV package manager (for building Python wheels)
Using the provided build script (Linux/macOS):
chmod +x build.sh
./build.shOr using Zig directly:
# Build dynamic library with optimizations
zig build -Doptimize=ReleaseFast
# Run tests
zig build testC Example:
# Build C example (after building library)
gcc -o zx12_example \
examples/c/example.c \
-L./zig-out/bin -lzx12 \
-I./include \
-Wl,-rpath,./zig-out/bin
# Run it
./zx12_example samples/837p_example.x12 schema/837p.jsonPython Example:
python3 examples/python/zx12_example.py samples/837i_example.x12 schema/837i.jsonThe zX12 library can be built using either the build.sh script or Zig directly.
The build script handles platform detection and builds both shared and static libraries:
./build.sh # Build library only
./build.sh --build-c-example # Build library and C exampleThis produces:
zig-out/bin/libzx12.so(Linux)zig-out/bin/libzx12.dylib(macOS)zig-out/bin/zx12.dll(Windows)zig-out/bin/libzx12.a(static library, all platforms)
# Debug build (faster compilation, slower runtime)
zig build
# Release build with optimizations
zig build -Doptimize=ReleaseFast
# Release build with small binary size
zig build -Doptimize=ReleaseSmall
# Release build with safety checks
zig build -Doptimize=ReleaseSafeBuild Options:
ReleaseFast- Maximum runtime performance (recommended for production)ReleaseSmall- Optimized for binary sizeReleaseSafe- Optimizations with runtime safety checksDebug- No optimization, full debug info (default)
The Python package includes pre-built binaries for:
- Linux (x86_64)
- macOS (x86_64 and ARM64/Apple Silicon)
- Windows (x86_64)
- Install UV package manager:
- Set the ZX12_PATH environment variable:
# Linux/macOS
export ZX12_PATH=/path/to/zX12
# Windows (PowerShell)
$env:ZX12_PATH = "C:\path\to\zX12"# Build wheel for all platforms
uv build
# Output will be in ./dist/
# Example: dist/zx12-0.1.0-py3-none-any.whlThe build process:
- Compiles the Zig library for multiple targets
- Bundles platform-specific binaries
- Packages everything into a wheel file
# Install from built wheel
pip install dist/zx12-0.1.0-py3-none-any.whl
# Or install in development mode
pip install -e .The C API provides a simple interface for parsing X12 documents:
#include "zx12.h"
#include <stdio.h>
#include <stdlib.h>
int main(void) {
// Initialize the library
zx12_init();
ZX12_Output* output = NULL;
int result = zx12_process_document(
"samples/837p_example.x12",
"schema/837p.json",
&output
);
if (result == ZX12_SUCCESS) {
// Get JSON output
const char* json = zx12_get_output(output);
printf("%s\n", json);
// Write to file
FILE* fp = fopen("output.json", "w");
if (fp) {
fprintf(fp, "%s", json);
fclose(fp);
}
// Clean up
zx12_free_output(output);
} else {
fprintf(stderr, "Error: %s\n", zx12_get_error_message(result));
}
zx12_deinit();
return 0;
}Compiling:
gcc -o myapp myapp.c -L./zig-out/bin -lzx12 -I./include -Wl,-rpath,./zig-out/binThe Python bindings provide a high-level, Pythonic interface:
from zx12 import ZX12Parser
# Create parser instance
parser = ZX12Parser()
# Parse X12 file to JSON
result = parser.parse_file(
x12_path='samples/837i_example.x12',
schema_path='schema/837i.json'
)
# Result is a Python dictionary
print(f"Transaction ID: {result['transaction']['id']}")
print(f"Billing Providers: {len(result['billing_providers'])}")
# Access nested data
for provider in result['billing_providers']:
for subscriber in provider.get('subscribers', []):
for patient in subscriber.get('patients', []):
for claim in patient.get('claims', []):
print(f"Claim ID: {claim['claim_id']}")
print(f"Total Charge: {claim['total_charge']}")Using Context Manager:
from zx12 import ZX12Parser
with ZX12Parser() as parser:
result = parser.parse_file('input.x12', 'schema.json')
# Parser automatically cleaned up on exitError Handling:
from zx12 import ZX12Parser, ZX12Error
try:
parser = ZX12Parser()
result = parser.parse_file('input.x12', 'schema.json')
except ZX12Error as e:
print(f"Parsing failed: {e}")
except FileNotFoundError as e:
print(f"File not found: {e}")The parser uses JSON schemas to define how X12 segments are transformed into JSON. This allows supporting new transaction types without modifying code.
{
"schema_version": "1.0.0",
"transaction": {
"id": "837P",
"version": "005010X222A1",
"type": "837",
"description": "Health Care Claim: Professional"
},
"hierarchical_structure": {
"output_array": "billing_providers",
"levels": {
"20": {
"name": "Billing Provider",
"segments": [
{
"id": "NM1",
"qualifier": [0, "85"],
"group": ["NM1", "N3", "N4", "REF"],
"elements": [
{ "seg": "NM1", "pos": 2, "path": "organization_name" },
{ "seg": "N3", "pos": 0, "path": "address_line_1" },
{ "seg": "N4", "pos": 0, "path": "city" },
{ "seg": "N4", "pos": 1, "path": "state" }
]
}
],
"child_levels": ["22"]
}
}
}
}For comprehensive schema documentation, see Schema Documentation, which covers:
- Parser behavior and conventions
- Element indexing and mapping
- Segment groups and qualifiers
- Hierarchical structures
- Non-hierarchical loops
- Repeating elements
- Common patterns
- Best practices
- Troubleshooting
| Function | Description |
|---|---|
zx12_init() |
Initialize the library (call once per process) |
zx12_deinit() |
Clean up library resources |
zx12_process_document() |
Parse an X12 file with a schema |
zx12_get_output() |
Get JSON string from output object |
zx12_free_output() |
Free output object and its resources |
zx12_get_error_message() |
Get human-readable error message |
Return Codes:
ZX12_SUCCESS(0) - Operation successfulZX12_ERROR_INVALID_ARGS(1) - Invalid argumentsZX12_ERROR_FILE_NOT_FOUND(2) - File not foundZX12_ERROR_PARSE_FAILED(3) - Parse errorZX12_ERROR_MEMORY(4) - Memory allocation failedZX12_ERROR_SCHEMA_INVALID(5) - Invalid schemaZX12_ERROR_UNKNOWN(99) - Unknown error
For detailed C API documentation, see C API Summary.
The Python API is documented in the module docstrings:
import zx12
help(zx12.ZX12Parser)The samples/ directory contains example X12 files:
837p_example.x12- Professional health care claim837i_example.x12- Institutional health care claim
C Example:
# After building the library and C example
./zx12_example samples/837p_example.x12 schema/837p.jsonPython Example:
# Using the standalone example
python3 examples/python/zx12_example.py samples/837i_example.x12 schema/837i.json
# Or using the installed package
python3 -c "
from zx12 import ZX12Parser
parser = ZX12Parser()
result = parser.parse_file('samples/837i_example.x12', 'schema/837i.json')
print(result['transaction']['id'])
"# Run all Zig tests
zig build test
# Run tests with verbose output
zig build test -- --verbosesrc/x12_parser/- Core parser implementationtokenizer.zig- X12 tokenizationx12_parser.zig- Segment parsinghl_tree.zig- Hierarchical structureschema.zig- Schema loading and validationdocument_processor.zig- Main processing logicjson_builder.zig- JSON output generation
- Create a schema file in
schema/(e.g.,schema/270.json) - Define the transaction structure following the schema format
- Test with sample X12 files
- No code changes needed!
See Schema Documentation for details on schema structure.
Currently tested and supported:
- 837P - Health Care Claim: Professional (005010X222A1)
- 837I - Health Care Claim: Institutional (005010X223A2)
The schema system is designed to support any X12 transaction set. Additional schemas can be added without modifying the parser code.
If you get "library not found" errors:
# Add library path to LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(pwd)/zig-out/bin
# Or copy library to system location
sudo cp zig-out/bin/libzx12.so /usr/local/lib/
sudo ldconfigIf Python can't find the library:
# Make sure wheel is installed
pip install -e .
# Or set PYTHONPATH
export PYTHONPATH=$(pwd)/python:$PYTHONPATHIf Zig build fails:
# Clean build cache
rm -rf zig-cache zig-out .zig-cache
# Rebuild
zig build -Doptimize=ReleaseFastContributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Submit a pull request
This project is licensed under the MIT License. See the LICENSE file for details.
- Documentation: Schema Documentation
- API Reference: C API Summary
- Repository: GitHub
- Issues: Bug Tracker
- Jacob Wilson - jjw07006@gmail.com
- Josh Lankford - lankford.josh@gmail.com
Built with Zig - A general-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.