What is preserved, and what is not¶
The guarantee is stated precisely here, including its limits, because a preservation library that is vague about what it preserves is worse than no library at all.
Preserved¶
| Comments | Attached to the same keys. This is the headline guarantee. |
| Key order | Documents come back in the order they were written. |
| Quoting style | "double", 'single' and bare scalars stay as they were. |
| Block scalars | Literal (\|) and folded (>) blocks keep their style. |
| Anchors and aliases | &anchor and *alias are not expanded. |
| Merge keys | <<: *base stays as written, not rewritten with an explicit tag. |
| Astral-plane characters | Emoji and other 4-byte characters stay literal, not escaped. |
| Every document | Multi-document files keep all documents and separators. |
Not preserved¶
| Blank lines | Blank-line grouping between sections is not retained. |
| Indentation width | Normalised on emit. |
| Inline comment alignment | Columns are collapsed to a single space. |
The --- marker |
Not added to a single-document file that lacked one. |
| Byte-identity | An untouched file is not guaranteed byte-for-byte identical. |
Never¶
Bytes that do not parse. Every emit re-parses its own output before returning it. If the result would not parse, you get an error, not a damaged document. This is not a best-effort promise — it is a hard invariant, and it is tested by fuzzing the mutation paths.
Why byte-identity is out of scope¶
Byte-identity would require splicing — patching only the changed bytes of the original, rather than re-emitting the document from its parsed form.
That needs each node's byte range, and no Go YAML library exposes one. The closest available is a rune offset that additionally drifts by one for every preceding comment, so a splicing implementation would have to build and maintain its own line index, walk block-scalar spans by hand, and solve insertion separately.
That is a substantial amount of fragile machinery to protect blank lines and comment alignment. The judgement made here is that comment survival is what people actually care about, and formatting normalisation is a fair price. If your use case genuinely needs byte-identity, this is the wrong library and it is better to know that early.
Stability across repeated edits¶
Emission converges immediately: writing a document twice produces the same bytes both times. A tool that saves on every keystroke will not accumulate drift, and a file under version control settles after its first write rather than producing noise on each save.