Skip to content

yamldoc

Edit a YAML document without destroying it.

Parse bytes, change one key, write bytes back. Comments stay attached to the keys they describe, key order holds, quoting and block styles survive, and everything you did not touch comes back semantically unchanged.

f, _ := yamldoc.Parse(src)
f.Documents()[0].Set("server.port", 9090)
out, _ := f.Bytes()
 server:
   host: localhost      # where we bind
-  port: 8080
+  port: 9090
   # end of the server block

The problem it solves

Marshalling a map[string]any back to YAML throws away every comment the author wrote, reorders keys, and reformats the file. That is fine for machine-written data and unacceptable for a hand-authored config file someone has to keep maintaining — which is exactly the file a CLI or settings UI needs to edit.

Go has the YAML value half many times over and the editing half not at all. Every other ecosystem splits the two: Rust's toml_edit and toml, HashiCorp's hclwrite and hclsyntax, Python's tomlkit and tomli. This is that split, for Go and YAML.

See Why not just re-marshal? for the detail.

Where to start

Scope

The library moves text. Meaning belongs to whoever is using it.

No file I/O. No merging, precedence or overlay semantics. No schema or validation. It assigns no meaning to the order of documents in a multi-document file. See Mechanism, not policy.