Skip to content

YAMLRocks vs yaml-rs

yaml-rs is a young Rust-backed YAML 1.2 parser that markets itself as the fastest in the ecosystem. It is genuinely fast, and the closest competitor to YAMLRocks on raw throughput. But it is only a parser: text in, Python values out. YAMLRocks is the whole toolkit real configuration work needs, comment-preserving round-trip, native includes, schema validation, source locations, rigorously verified correctness, and it is faster on top.

Featureyaml-rsYAMLRocks
YAML 1.2YesYes
Comment-preserving round-tripNoYes (byte-for-byte)
Native !include + writebackNoYes
JSON Schema validationNoYes (line-numbered)
Source line/columnNoYes (annotated mode)
Custom tag handlingNoYes
Verified vs the YAML suiteNot statedYes, in full
Anchors/aliases resolvedYesYes
Merge keys (<<)NoYes
Timestamp resolutionOn by default, incl. quotedOpt-in, plain scalars only
ImplementationRust (saphyr fork)Rust (own scanner/emitter)
Speed (parse / dump)baseline~1.2x / ~1.3x faster
Maturity0.1.x, public domainBattle-tested corpus

This is the difference that matters. yaml-rs reads YAML into Python values and stops there. YAMLRocks does that and everything a real configuration workflow needs around it:

  • Comment-preserving round-trip. Load with OPT_ROUND_TRIP, change a value, and re-emit with every comment, anchor, and formatting choice intact; an unmodified document comes back byte-for-byte. yaml-rs discards comments and layout, so it cannot edit a file, only read it.
  • Native !include. YAMLRocks resolves !include and the !include_dir_* family, and in round-trip mode writes edits back to the specific file each node came from. Split configurations (Home Assistant, Kubernetes overlays) work out of the box.
  • JSON Schema validation with line-numbered errors, so a bad config is rejected with a message that points at the line, not a stack trace.
  • Annotated mode attaches the source line and column to every node, which is what lets a tool underline the exact place a value came from.
  • Custom tag handling through a tags= registry or a tag_handler.
  • Safe by default. Loading never constructs arbitrary Python objects.

See round-trip editing, includes, schema validation, and annotated mode.

Both are Rust extensions, so this is Rust vs Rust, not Rust vs Python. yaml-rs is the nearest rival on the field, and YAMLRocks is still ahead on both directions.

YAMLRocks vs yaml-rs on reading and writing: YAMLRocks is faster on both loads and dumps.

Operationyaml-rsYAMLRocksYAMLRocks is
Reading~2.1 ms~1.7 ms~1.2x faster
Writing~1.3 ms~1.0 ms~1.3x faster

The gap is smaller than against a pure-Python library, as you would expect from two native implementations. Speed is real, but it is not the reason to choose between them, the capabilities above and the correctness below are.

YAMLRocks’s parsing is checked against the entire official YAML test suite on every change: a case must load, round-trip, and match its canonical result, or CI fails. That is the substantive correctness claim, and it is why the edges hold up. yaml-rs makes no such published guarantee, and it shows in cases like these:

import yamlrocks
# Merge keys: YAMLRocks folds the base in; yaml-rs leaves `<<` as a literal key.
yamlrocks.loads(b"base: &b\n timeout: 30\nsvc:\n <<: *b\n name: api\n")
# {'base': {'timeout': 30}, 'svc': {'timeout': 30, 'name': 'api'}}
# Leading-zero integers: `0777` is a string in YAML 1.2, not the number 777.
yamlrocks.loads(b"mode: 0777")
# {'mode': '0777'}

Timestamps are a sharper example. yaml-rs resolves a date/datetime scalar to a Python object by default, and it does so even for a quoted scalar. In YAML a quoted scalar is explicitly a string, so quoting is exactly how you say “keep this as text”, and yaml-rs ignores that. YAMLRocks makes timestamp resolution opt-in (OPT_TIMESTAMPS) and only ever applies it to plain scalars, matching PyYAML and the spec:

import yamlrocks
# A quoted scalar is a string, even with timestamp resolution enabled.
yamlrocks.loads(b'when: "2024-01-15"', option=yamlrocks.OPT_TIMESTAMPS)
# {'when': '2024-01-15'}
# yaml-rs returns {'when': datetime.date(2024, 1, 15)}, quoting ignored.

These are not the reason to switch on their own; they are evidence that “verified against the whole suite” is a real difference, not a slogan.

yaml-rs is a small, fast, public-domain (Unlicense) parser. If all you need is to turn a trusted YAML 1.2 file into Python data as quickly as possible, and never write YAML back out, it does that one job well. It is early software (0.1.x) with a deliberately thin surface.

Choose YAMLRocks when YAML is something you edit and depend on, not just read: comment-preserving round-trip, native includes, schema validation, and source locations, on a parser that is verified correct against the full YAML test suite and is faster too. That is almost every real configuration use.