LEPTRIS
YAML Ain’t Markup — parsed at library speed

YAML, parsed at
library speed.

yeptris is the YAML counterpart of libleptris: a YAML 1.2 parser, writer and streamer in pure C11 — zero required dependencies, a stable C ABI, opaque handles — with a Psych-compatible Ruby gem and a PyYAML-compatible Python package shaped like the incumbents.

  • Speed with a referee — every figure comes from the open benchmark lane: interleaved runs, pinned competitors, medians, a performance ledger kept in the repository.
  • Conformance first — 395/395 on the yaml-test-suite, the libyaml emission goldens with zero divergences, ASan/UBSan/TSan suites, and a nightly libFuzzer lane.
  • One core, three surfaces — the same C11 engine from C, Ruby, and Python; bindings version in lockstep with the engine.
the fourth hare joins the chase
0/395yaml-test-suite
0×scalar-heavy vs libyaml, dev hardware
0libyaml emission goldens, zero divergences
0prebuilt platform gems, lockstep releases
zerorequired runtime dependencies

What it is

An engine built like a ledger, not a claim

yeptris is YAML 1.2 first — with a libyaml/Psych-compatible YAML 1.1 lenient mode for the real world. The yaml-test-suite is the conformance bar; every divergence is documented; every performance statement reproduces from the benchmark harness and the ledger (benchmarks/PERF-LEDGER.md).

up to 3.36× / libyaml, per shape

The race, in the open

Same-binary, min-of-N against libyaml: scalar-heavy 3.36×, block-nested ~2.3×, wide mappings ~2.4×, anchor-heavy ~1.8×. The interleaved head-to-head against rapidyaml runs in CI on every push — nine document shapes across DOM, pull, recorder and emit.

395/395 yaml-test-suite

Conformant where it counts

The full verification matrix: yaml-test-suite pinned atda267a5, psych-pure’s 67 corpus files, JSONTestSuite 95/95 accept and 188/188 reject in strict mode, 405-input libyaml parse differential with full-record equality, 1091 fuzz inputs across chunkings.

1 C call per document free

Beyond the DOM

Three consumption models over one engine: pull events (StAX-style, zero C→host callbacks — the FFI-friendly form), libyaml-compatible push events, and a packed record tape for bulk drains. Plans and schemas walk documents into typed columns with no intermediate tree. Zero-copy value views in C.

14 prebuilt gem rows · abi3 wheels

Packaging that installs

Ruby: fat platform gems (no C extension — FFI), every major OS×arch tier, lockstep-released with the engine. Python: self-contained wheels over ctypes, zero compilation at install. C: cmake --install with pkg-config.

The surface

Shaped like the incumbents

Ruby mirrors Psych (its YAML 1.1 implicit typing is the default; schema: :core_12 switches to the 1.2 core schema), and drops in beside it — including the error names. Python mirrors PyYAML’s safe surface.

#include <yeptris/yeptris.h>

YeptrisStatus st;
YeptrisDocument doc = yeptris_parse(data, len, &st);
if (!doc) {
    uint32_t line, col;
    const char *msg = yeptris_last_error(&line, &col);  /* 1-based */
}
size_t n = yeptris_document_count(doc);
YeptrisNode root = yeptris_document_root(doc, 0);
YeptrisNode port = yeptris_node_map_get(root, "port", 4);

char *out = NULL; size_t out_len = 0;
out = yeptris_serialize(doc, &out_len);      /* canonical YAML */
yeptris_document_free(doc);                  /* one free for everything */

The chase begins

Install, three ways

surfacecommandwhat you get
Rubygem install yeptrisa prebuilt platform gem where one exists — FFI over the shared library, zero compilation at install
Pythonpip install yeptrisa self-contained wheel — ctypes FFI over libyeptris, PyYAML-compatible semantics
Ccmake -B build -S . && cmake --build buildLTO on by default; cmake --install carries headers and pkg-config

The yeptris docs — C, Ruby and Python guides →

Fast as hares.
Parsed at library speed.

yeptris v0.6.22 — libyeptris v0.6.22, the yeptris gem v0.6.22.1, the yeptris package v0.6.22.1. Repos canonical: yeptris, yeptris-ruby, yeptris-py.