YAML vs JSON
| Feature | JSON | YAML |
|---|---|---|
| Comments | Not supported | # comment to end of line |
| Strings | Double quotes required | Unquoted, single or double |
| Multiline strings | \n escape only | | literal block or > folded |
| Anchors & references | Not supported | &anchor and *reference |
| Multiple documents | One per file | --- separator between documents |
| Indentation | Not significant (braces) | Significant (2 spaces, no tabs) |
| Numbers | Integer, float | Integer, float, hex (0x), octal (0o) |
| Dates | String only | Native date type (yyyy-mm-dd) |
| Booleans | true / false only | true/false, yes/no, on/off (deprecated) |
| Null | null | null, ~, or empty value |
YAML and JSON describe the same data structures - maps, lists, strings, numbers - but serve different masters. JSON is optimised for machines: unambiguous, fast to parse, no comments, mandatory quotes. YAML is optimised for humans: comments, anchors to reduce duplication, and indentation-based structure that is readable but has a terrifying edge-case catalogue.
The key insight: YAML 1.2 is a strict superset of JSON - every valid JSON document is valid YAML 1.2 - so switching config from JSON to YAML is always safe, but the reverse can break on comments, anchors or unquoted strings.
How to use
- Filter by feature to compare how each format handles it - comments, anchors, indentation, dates.
- Use the rule of thumb: JSON for APIs (machine-to-machine), YAML for configuration (human-to-machine).
- Watch the indentation row: YAML is whitespace-sensitive, JSON is brace-delimited - the #1 source of YAML parsing errors.
Frequently asked questions
Can I put comments in JSON?
No - RFC 8259 does not define a comment syntax. The JSON creators intentionally excluded comments because they are metadata, not data. Workarounds: a "_comment" key (ugly but common), or use YAML/JSON5/TOML for config files where comments are essential.
What is a YAML anchor and why is it useful?
Anchors (&name) tag a value for reuse, and aliases (*name) reference it: default: &default timeout: 30 retries: 3, then staging: <<: *default. This eliminates duplication in large config files like Docker Compose and Kubernetes manifests. JSON has no equivalent - you copy-paste or use code to merge.
Why does YAML have a reputation for being dangerous?
The Norway problem (no becomes false in YAML 1.1), accidental type coercion (version: 1.20 becomes 1.2), and the billion laughs attack (exponential anchor expansion) all come from YAMLโs implicit type resolution and recursive aliasing. YAML 1.2 fixed the booleans; safe_load() fixes the attacks.
Which should I use for Kubernetes manifests?
Kubernetes only accepts YAML (and JSON, which is valid YAML). The YAML anchors and multi-document features make it the natural choice for K8s configs. For API payloads, JSON is universal - every language parses it natively, and the lack of comments prevents config drift in production.