One compact library that parses, validates, acknowledges, and rebuilds EDI — at native speed
Native performance
Compiled to native code with zero-copy UTF-8 buffers and streaming split/merge for high-throughput EDI processing.
Zero dependencies
A single self-contained shared library per platform. No .NET runtime, JVM, or install step needed on the target machine.
EDI ↔ JSON conversion
Parse a whole X12 interchange to transaction-set JSON in one call with parse, and build it back to X12 with build.
Streaming split & merge
Process one transaction set or segment at a time with flat, low memory use — ideal for very large interchange files.
Built-in validation
Validate transaction sets with configurable SNIP levels, regex, date/time formats, and error limits, for a detailed report.
Acknowledgments
Automatically generate 999, 997, and TA1 acknowledgments from validated interchanges in a single operation mode.
Parse EDI in a few lines
import ctypes, json lib = ctypes.CDLL("./edifabric-x12-tools.so") # .dll / .dylib on other OSes lib.parse.restype = ctypes.c_int def set_map(map_json: str): b = map_json.encode("utf-8") if lib.set_map(b, len(b)) != 0: raise RuntimeError("set_map failed") def parse(edi: bytes, mode: int = 1) -> str: cap = len(edi) * 12 out_len = ctypes.c_int(0); out_off = ctypes.c_int(0) while True: out = ctypes.create_string_buffer(cap) rc = lib.parse(edi, len(edi), mode, None, 0, out, cap, ctypes.byref(out_len), ctypes.byref(out_off)) if rc == 1: # InsufficientCapacity — grow & retry cap = out_len.value; continue if rc != 0: raise RuntimeError(f"parse failed: {rc}") return out.raw[:out_len.value].decode("utf-8")
// P/Invoke into the native library [DllImport("edifabric-x12-tools", EntryPoint = "parse")] static extern unsafe int Parse(byte* input, int inputLen, int mode, byte* config, int configLen, byte* output, int outputCap, int* outputLen, int* outputOffset); static unsafe string Parse(byte[] edi, int mode = 1) { int cap = edi.Length * 12, len, off; while (true) { var outBuf = new byte[cap]; fixed (byte* pIn = edi, pOut = outBuf) { int rc = Parse(pIn, edi.Length, mode, null, 0, pOut, cap, &len, &off); if (rc == 1) { cap = len; continue; } // grow & retry if (rc != 0) throw new Exception($"parse failed: {rc}"); return Encoding.UTF8.GetString(outBuf, 0, len); } } }
/* Declare the entry points exported by the native library */ extern int set_map(const unsigned char* map, int len); extern int parse(const unsigned char* in, int inLen, int mode, const unsigned char* cfg, int cfgLen, unsigned char* out, int cap, int* outLen, int* outOff); extern void* get_error(int code); /* EDI -> JSON, growing the buffer once if it is too small */ int edi_to_json(const unsigned char* edi, int ediLen, unsigned char** out, int* outLen) { int cap = ediLen * 12, off = 0; *out = malloc(cap); int rc = parse(edi, ediLen, 1, NULL, 0, *out, cap, outLen, &off); if (rc == 1) { /* InsufficientCapacity */ *out = realloc(*out, *outLen); rc = parse(edi, ediLen, 1, NULL, 0, *out, *outLen, outLen, &off); } return rc; /* 0 = success */ }
Language-agnostic ABI
A handful of C entry points returning integer status codes — call it from C, C++, Rust, Go, Python, Node.js, or Java/JNA.
Flexible licensing
Choose offline tokens for containers and air-gapped, high-volume workloads, or simple online serial validation.
Configurable models
Map any transaction set (837P, 834, 850, …) to model files with a single JSON map, or fall back to the online spec service.