YAML for Go

github.com/malcolmston/yaml

YAML 1.2 with zero dependencies — the one Go's stdlib never shipped.

 GitHubports yaml/pyyaml

A complete YAML 1.2 parser and emitter built entirely on the Go standard library — no third-party modules, no cgo, no require directives. This is the port with the clearest reason to exist: Go has no stdlib YAML, so every project reaches for a third-party module. <code>Marshal</code> and <code>Unmarshal</code> cover the one-shot cases, <code>NewDecoder</code> walks a multi-document stream and returns <code>io.EOF</code> after the last <code>---</code>, and <code>Node</code> is a lossless document model that keeps anchors, styles, line/column and head/line/foot comments so you can rewrite a file without flattening it. Tag resolution follows the YAML <b>1.2 core schema</b>, so <code>no</code> is the string "no" rather than false — the Norway problem does not apply. Verified against the language-agnostic yaml-test-suite. The import path is github.com/malcolmston/yaml.

Install

shell
$ go get github.com/malcolmston/yaml

Quick start

main.go
import "github.com/malcolmston/yaml"

var cfg struct {
    Name  string            `yaml:"name"`
    Ports []int             `yaml:"ports"`
    Env   map[string]string `yaml:"env"`
}
if err := yaml.Unmarshal(src, &cfg); err != nil {
    log.Fatal(err)         <span class="tok-c">// *TypeError lists every bad field
}
fmt.Println(cfg.Ports[1])

out, _ := yaml.Marshal(cfg)

Features

  • Marshal / Unmarshal onto structs, maps, slices and any, with struct tags yaml:"name,omitempty", yaml:"-", yaml:",inline", yaml:",flow"
  • Streaming multi-document I/O — NewDecoder(r).Decode(&v) returns io.EOF past the last document; NewEncoder(w) with SetIndent and Close
  • Full block and flow syntax — block and flow collections, explicit ?/: keys, block scalars | and > with chomping and explicit indent indicators, quoted scalars with the complete escape table
  • Anchors, aliases and merge keys (&a, *a, <<) — with an alias-expansion budget, so a billion-laughs document is rejected instead of exhausting memory
  • YAML 1.2 core schema resolution — null/bool/int (decimal, octal, hex)/float including .inf and .nan/string, plus explicit !!str, !!int, !!binary … tags
  • Node keeps Kind, Tag, Value, Anchor, Style, Line/Column and HeadComment/LineComment/FootComment, with Node.Decode / Node.Encode for comment-preserving round-trips
  • TypeError collects per-field decode failures instead of aborting the whole decode
  • Marshaler / Unmarshaler plus encoding.TextMarshaler / TextUnmarshaler support
  • Wrapped sentinel errors — ErrSyntax, ErrUnknownAnchor, ErrAliasBomb, ErrTypeMismatch — all matchable with errors.Is, and syntax errors carry line and column
  • Zero dependencies — pure Go standard library, no cgo, nothing to audit but the toolchain
YAML