Fast
Parsing runs about 5 to 10 times faster than PyYAML’s C loader, and dumping
about 15 to 19 times faster. Native !include resolution over hundreds of
files is roughly 18 times faster than a PyYAML constructor.
YAMLRocks is the rock-solid YAML library for Python: a Rust-backed extension that parses and emits YAML fast, follows the YAML 1.2 specification (with a YAML 1.1 compatibility mode), and, unlike PyYAML, round-trips documents while preserving comments, anchors, and formatting. Correct, secure by default, and fast, with Rust at the core (the R in Rock).
The API is small and predictable: loads and dumps for in-memory data, load and dump for files,
to_json to export JSON, integer OPT_* flags combined with |, and dumps
returning bytes. Reach for a flag only when you need to, and the defaults stay
fast and correct.
Created and written by Franck Nijhof, also known as Frenck.
Read the story behind YAMLRocks.
Fast
Parsing runs about 5 to 10 times faster than PyYAML’s C loader, and dumping
about 15 to 19 times faster. Native !include resolution over hundreds of
files is roughly 18 times faster than a PyYAML constructor.
Correct
A custom YAML 1.2 scanner and parser, exercised against the official YAML test suite plus snapshot and fuzz corpora, and actively tested against thousands of real-world configuration files from dozens of public repositories across many ecosystems. See real-world verification.
Secure
No code execution from tags, safe by default, and hardened against alias bombs and deeply nested input. Includes stay confined to their base directory, so a document cannot reach arbitrary files on disk.
Round-trip
Preserve comments, anchors, scalar styles, flow-versus-block layout, and an
explicit --- marker. Edit a value and re-emit with the rest of the
document preserved, including unmodified included files.
Async-friendly
Await async_load to parse off the event loop (the native parse releases
the GIL, so other tasks keep progressing) and async_dump to write files
without blocking it. The extension is built for free-threaded (no-GIL)
CPython, too.
Batteries included
YAML 1.1 mode, source-location annotations, native !include resolution
with write-back, JSON export, JSON Schema validation (including in-file
$schema references), and a PyYAML-compatible shim.
Parse YAML into native Python objects, and serialize them back to bytes:
import yamlrocks
source = """key: valuelist: - 1 - 2"""
data = yamlrocks.loads(source)# {'key': 'value', 'list': [1, 2]}
yamlrocks.dumps(data)# b'key: value\nlist:\n - 1\n - 2\n'Edit a value while keeping comments, anchors, and layout untouched:
import yamlrocks
doc = yamlrocks.loads(b"# app config\nname: app # service\nport: 8080\n", option=yamlrocks.OPT_ROUND_TRIP)doc["port"] = 9090doc.to_yaml()# b'# app config\nname: app # service\nport: 9090\n'Export the same data to JSON with to_json (JSON is valid YAML 1.2, so loads
already reads it back):
import yamlrocks
source = """name: appports: [80, 443]"""
yamlrocks.to_json(yamlrocks.loads(source))# b'{"name":"app","ports":[80,443]}'In an asyncio application, await the load so it runs off the event loop
thread. The native parse releases the GIL, so other tasks keep progressing:
import asyncioimport yamlrocks
source = """key: valuelist: - 1 - 2"""
async def main(): return await yamlrocks.async_loads(source)
asyncio.run(main())# {'key': 'value', 'list': [1, 2]}YAMLRocks beats PyYAML’s C loader and leaves pure-Python round-trip libraries far behind. Release-build benchmarks, showing how many times faster YAMLRocks is:
| Operation | vs PyYAML (C) | vs ruamel.yaml |
|---|---|---|
Parse ( | ~5-10x faster | ~85-135x faster |
Serialize ( | ~15-19x faster | ~155-210x faster |
Split config ( | ~18x faster | n/a |
See the full comparisons and performance guide. Planning a migration? Start with the migration compatibility matrix.
Trust matters when a parser edits configuration people maintain by hand.
YAMLRocks is continuously tested against a reproducible corpus of public YAML
repositories across Home Assistant, ESPHome, Ansible, Kubernetes, Docker Compose,
GitHub Actions, CloudFormation, GitOps, Helm, OpenAPI, dbt, CircleCI,
Serverless, and Tekton. Every standalone YAML file must parse and re-emit
byte-for-byte in round-trip mode, and selected Home Assistant configurations are
loaded through their full !include graph.
These projects do not endorse or depend on YAMLRocks; their public repositories are used as a compatibility corpus so regressions are caught against YAML that people actually write and maintain. See the real-world verification page for the current corpus and scope.
Round-trip a split configuration, edit a value that lives in an included file, and write only the file that changed back to disk:
import yamlrocks
# Load a Home Assistant config with includes, round-trip modedoc = yamlrocks.load( "configuration.yaml", option=yamlrocks.OPT_ROUND_TRIP | yamlrocks.OPT_INCLUDES,)
# Edit a value that lives in an included filedoc["automation"][0]["trigger"]["at"] = "07:30:00"
# Save: only the changed file is rewritten, comments and the rest intactdoc.save()