Comparison guide
JSON vs YAML: Choosing a Config Format
JSON vs YAML compared on readability, comments, tooling, and gotchas. Concrete examples and a clear recommendation for each common config use case.
Every config file in modern infrastructure is JSON or YAML. They look similar at a glance, but the differences matter the moment you write something more complex than a flat object. Picking the right one saves debugging time; picking the wrong one introduces silent bugs that surface in production.
Convert between the two with the JSON to YAML converter, or read on for a structural comparison and a clear recommendation per use case.
Quick answer
Use JSON when machines read the data and humans do not — APIs, message payloads, IPC. Use YAML when humans write the data and machines read it — Kubernetes manifests, GitHub Actions workflows, application config. JSON's strength is its simplicity; YAML's strength is readability and comments. Neither replaces the other.
Comparison at a glance
| Criterion | JSON | YAML |
|---|---|---|
| Comments | No | Yes (# to end of line) |
| Multi-line strings | Escaped only (\n) |
Native block scalars |
| Indentation matters | No | Yes (no tabs allowed) |
| Anchors / references | No | Yes (&id, *id) |
| Trailing commas | No | Not applicable |
| Spec versions in the wild | One (RFC 8259) | 1.1 vs 1.2 (causes real bugs) |
| Parser speed | Faster | Slower |
| Implicit type coercion | None | Substantial (and confusing) |
| Default in APIs | Yes | No |
| Default in config files | No | Yes |
| File extensions | .json |
.yaml, .yml |
Where JSON wins
Parser simplicity
JSON has one spec. Every well-formed JSON document parses identically in every language. There are no version dialects, no implicit type coercion, no surprises.
Speed
JSON parsers are some of the fastest in the language ecosystem — they're built into V8, the JVM, Go's standard library, Python's C extension. YAML libraries are typically pure-language ports that run an order of magnitude slower.
Format strictness
{
"service": "acme-api",
"replicas": 3,
"image": "acme/api:1.2.0"
}
Trailing commas are syntax errors. Comments are syntax errors. Strings must be
double-quoted. Numbers are numbers, strings are strings, and the parser will not
silently turn "yes" into true. Strictness is annoying when you're writing by
hand and a blessing when you're debugging a production payload.
Where YAML wins
Readability with nesting
service: acme-api
replicas: 3
image: acme/api:1.2.0
env:
NODE_ENV: production
LOG_LEVEL: info
ports:
- 80
- 443
No braces, no quotes for plain strings, no commas. For a config file edited by hand, the YAML version is materially easier to read than the JSON equivalent.
Comments
YAML supports comments — JSON does not. For config files where the why matters as much as the what, this alone is enough to choose YAML.
# Production override — match the load test from 2026-04-12.
replicas: 8
Multi-line strings
startup_script: |
#!/bin/bash
set -e
echo 'starting'
exec /app/bin/server
The | block scalar preserves newlines exactly. The equivalent JSON requires
escaping every newline as \n in a single quoted string — readable to the
parser, unreadable to humans.
The YAML gotchas that will bite you
The "Norway problem"
country_codes:
- US
- GB
- NO # ← In YAML 1.1, this becomes false
YAML 1.1 treats NO (and no, yes, on, off, y, n) as boolean
literals. The country code for Norway parses as false. YAML 1.2 narrowed this
to true/false, but most real-world parsers — including a chunk of Python's
PyYAML and Ruby's Psych — still ship YAML 1.1 behavior. Quote ambiguous strings:
"NO".
Version-number confusion
version: 1.10 # parsed as the float 1.1
Software versions are not floats. Quote them: version: "1.10".
Indentation traps
YAML rejects tabs for indentation. Mixing tabs and spaces — even visually identical ones — causes parse errors that don't always point at the right line. Configure your editor to insert spaces only, two per level.
Multiple specs, one extension
The .yaml file extension doesn't tell you whether the parser will use YAML 1.1
or 1.2 rules. The same file can parse differently in different services. Pin
your parser version and write defensively.
When to use which
Use JSON when
- The data flows machine-to-machine — HTTP APIs, queue messages, IPC.
- You care about parsing speed.
- You want strict, unambiguous syntax.
- Multiple languages need to read or write the same file (every language has a fast, identical JSON parser).
- Humans rarely read or write the file by hand.
Use YAML when
- Humans edit the file routinely — Kubernetes manifests, CI workflows, infrastructure-as-code.
- Comments would help future readers.
- The structure is deeply nested and readability matters.
- The tool ecosystem you're integrating with (Kubernetes, Ansible, GitHub Actions) expects YAML by convention.
Use neither
For application config that's written and read entirely within your codebase, consider TOML (Cargo, pyproject) or HCL (Terraform). They sidestep YAML's gotchas while staying readable.
Convert between them in the browser
The free JSON to YAML converter on JSONZen handles both directions client-side. Paste JSON, get readable YAML; paste YAML, get strict JSON. Useful when migrating a config file or generating one format from a template in the other.
You can also pre-format JSON with the JSON formatter or validate it against a schema before converting.
Closing recommendation
For APIs and machine-to-machine data, JSON is the default and there's no good reason to fight it. For human-edited config, YAML is the default — accept the gotchas, quote ambiguous values, and pin your parser. The mistake is using YAML for API payloads (slow, brittle) or JSON for hand-edited configs (unreadable, no comments).
Related guides
- JSON to YAML: Convert Config and Data Files
Convert JSON to YAML for config files, Kubernetes manifests, and CI pipelines. Step-by-step examples with multiline strings, comments, and edge cases.