YAML vs JSON: Which One Should Your Config Use?
The yaml vs json question almost never has a universal answer, because the two formats are tuned for opposite jobs. JSON is built for programs to exchange data; YAML is built for people to hand-edit config. Pick the wrong one and you either fight a wall of quotes and braces or you spend an afternoon chasing a value that silently turned into a boolean. This guide gives you a quick rule, the footguns of each, and when to reach for TOML instead. If you just need to move data across the line, the YAML to JSON converter handles the round trip in your browser.
Try the YAML ⇄ JSON toolConvert YAML to JSON and JSON back to YAML, both ways. Validates as it converts and shows clear errors. Everything runs in your browser.The 60-second difference
YAML is a strict superset of JSON, which means every valid JSON document is also valid YAML. The reverse is not true. YAML adds indentation-based structure, comments with #, anchors and references for reuse, and a small zoo of scalar types it infers without quotes. JSON adds none of that: braces, brackets, double-quoted keys, commas, and four primitive types (string, number, boolean, null). That smallness is the point. There is almost nothing to get wrong in JSON and almost nothing to argue about.
| Dimension | YAML | JSON |
|---|---|---|
| Comments | Yes, with # | No, not in the spec |
| Structure | Indentation (whitespace-sensitive) | Braces and brackets |
| Multi-line strings | Native, with | and > | Escaped \n inside one line |
| Type inference | Aggressive (the Norway problem) | Explicit, only four primitives |
| Reuse | Anchors and aliases (& and *) | None |
| Parsing risk | Higher, ambiguous edge cases | Low, one obvious reading |
| Best fit | Human-edited config | APIs and machine-to-machine |
Where YAML wins
YAML earns its place wherever a human reads and edits the file by hand. Kubernetes manifests, CI pipelines, Ansible playbooks, and Docker Compose all chose YAML for the same reasons. Comments let you explain why a setting exists, which is often more valuable than the setting itself. Indentation removes the closing-brace noise, so a deeply nested config stays readable. And multi-line strings are first class: a shell script or a certificate can sit inline without a single escaped newline.
# Block scalars keep newlines and indentation intact
startup:
command: |
set -euo pipefail
echo "booting"
./run --config prod.yaml
retries: 3 # inline comments survive in YAML, never in JSONWrite that same script as a JSON string and every newline becomes \n on a single long line. For anything a person maintains, that difference compounds fast.
The footguns: the Norway problem and indentation
YAML's convenience is also its hazard. The most famous case is the Norway problem: an unquoted no is parsed as the boolean false, so a list of country codes that includes NO (Norway) can lose that entry or turn it into a boolean. The same trap catches yes, on, and off, all of which older YAML parsers coerce to booleans. A version string like 1.20 may be read as the number 1.2, and a value like 0x10 may become an integer. The fix is blunt: quote anything that should stay a string.
The second footgun is whitespace. Because structure is indentation, a single stray tab or an off-by-two space changes the meaning of the document, and the error often surfaces far from the typo. Mixing tabs and spaces is rejected outright by most parsers. JSON has neither problem: its braces make nesting unambiguous, and a formatter can always reindent it without changing meaning.
Where JSON wins
For anything two programs exchange, JSON is the default and should usually stay that way. Every language ships a parser, every HTTP client speaks it, and there is exactly one way to read a given document. There is no type inference to second-guess, no indentation to corrupt in transit, and no anchors to expand. JSON is also faster to parse and far harder to make ambiguous, which matters when the producer and consumer are written by different teams in different languages.
- REST and GraphQL payloads, where ubiquity and speed beat readability.
- Log lines and event streams, where one record per line parses cleanly.
- Anything cached, signed, or hashed, where a single canonical form is required.
- package.json, tsconfig, and other files tools generate and rewrite.
TOML: a third option for app config
TOML sits between the two and is worth knowing. It reads like an INI file, supports comments, and has no significant whitespace, so the Norway problem and the indentation traps both disappear. Its types are explicit and its dates are first class. The trade-off is that TOML gets awkward once nesting goes more than a level or two deep, where YAML stays flatter. That is why you see TOML in Rust's Cargo.toml, Python's pyproject.toml, and many CLI configs, but rarely in Kubernetes-style documents with deep trees. If your config is mostly flat key-value settings, TOML is often the calmest choice of the three.
Converting between them, and what does not survive
Converting YAML to JSON is lossless for the data itself: every scalar, list, and map maps cleanly onto JSON's four primitives plus arrays and objects. Going the other way, JSON to YAML, is also clean because JSON is a YAML subset. What does not survive the trip is everything YAML adds on top of the data model.
- Comments. JSON has no place to put them, so # lines are dropped on the way in and never reappear on the way out.
- Anchors and aliases. They are expanded into duplicated values during conversion, so the reuse is gone even though the data is correct.
- Key order and formatting. Block scalars, flow style, and your chosen indentation are normalized away.
- Scalar intent. A quoted "NO" survives, but if it was already coerced to a boolean, the conversion cannot recover the original string.
In practice this means conversion is a one-way door for documentation and reuse. Treat one format as the source of truth and generate the other, rather than editing both. The YAML to JSON converter runs entirely in the browser, so a config full of secrets never leaves your machine, and it shows the parsed result so you can confirm that NO is still a string before you ship it.
When an edge case bites and you want the authoritative rule, go to the source. The behavior of every scalar, tag, and anchor is defined in the YAML 1.2 specification at yaml.org, which spells out exactly which strings the core schema treats as booleans, null, integers, or plain text. If a parser disagrees with you about Norway, that page is where you settle it.
The short version: reach for YAML or TOML when people maintain the file and comments matter, reach for JSON when programs trade the data and one canonical reading matters, and quote your ambiguous scalars no matter which you choose.
Convert YAML and JSON nowConvert YAML to JSON and JSON back to YAML, both ways. Validates as it converts and shows clear errors. Everything runs in your browser.Related articles
Turn a JSON Response into a TypeScript Interface in Seconds
Generate a TypeScript interface from any JSON response: optional fields, nullables, nested types, and where a single sample falls short.
Pretty-Print vs Minify: When to Format JSON and When to Compress It
When to format JSON for readable diffs and debugging, when to minify it for size, and how to do both privately in your browser.
How to Minify JSON to Shrink API Payloads
What minifying JSON actually removes, the realistic 20 to 40 percent size win, and why server compression usually matters more.