If you've worked with Kubernetes, GitHub Actions, or Docker Compose, you've written YAML. If you've called an API, you've received JSON. Both formats do the same basic job — they store structured data as text — but they were built for different readers, and picking the wrong one makes your life harder than it needs to be.
The short version
YAML is built for humans to read and edit by hand. JSON is built for machines to parse quickly and unambiguously. That one sentence explains almost every difference between them.
What the same data looks like in both
Here's a small config, written first in JSON:
{
"name": "web-service",
"port": 8080,
"env": ["staging", "production"],
"debug": false
}
And the same thing in YAML:
name: web-service
port: 8080
env:
- staging
- production
debug: false
Same data, same meaning. The YAML version has no braces, no brackets, and no trailing commas to get wrong. Indentation alone tells you what belongs to what. That's exactly why YAML feels friendlier to write by hand — and exactly why it's riskier for a machine to parse. A single misplaced space in YAML can silently change what a document means; JSON's stricter punctuation makes structure explicit, so a parser either accepts a document or rejects it outright, with far less room for silent misinterpretation.
Where YAML wins
- Configuration files people edit by hand. Kubernetes manifests, CI/CD pipelines (GitHub Actions, GitLab CI, CircleCI), Ansible playbooks, and Docker Compose files are all YAML, because someone is going to open that file in an editor and change a value.
- Comments. YAML supports
#comments. JSON has no comment syntax at all — you simply cannot leave a note explaining why a value is set the way it is. - Multi-line strings. YAML has clean syntax for block text (using
|or>), which is handy for embedding scripts or long descriptions directly in a config file. - Less visual noise. No commas to forget, no closing braces to count. For a human skimming a file, that matters.
Where JSON wins
- APIs and data interchange. Practically every REST API on the internet speaks JSON. It's the native format of JavaScript, and every major language has a fast, built-in or near-built-in JSON parser.
- Unambiguous parsing. Because whitespace doesn't carry meaning in JSON, a JSON document either parses or it doesn't. There's no equivalent to a YAML indentation bug quietly changing which key belongs to which parent.
- Speed. JSON parsers are generally faster than YAML parsers, because the format is simpler to tokenize. At API scale, with thousands of requests per second, that difference adds up.
- Universality in tooling. Browsers parse JSON natively. Databases like MongoDB and PostgreSQL (via
jsonb) store it directly. Logging pipelines expect it. JSON is the lingua franca.
The famous YAML gotchas
YAML's flexibility is also where it bites people. A few classics worth knowing before you get burned by them:
- The Norway problem. In YAML, an unquoted
nois interpreted as the booleanfalse(andyesastrue), because early YAML versions treated them as boolean aliases. A country code field containingNOfor Norway can silently turn intofalse. The fix is simple — always quote strings that could be mistaken for booleans — but it's a real bug people hit in production. - Tabs are not allowed for indentation. YAML requires spaces. A stray tab character (easy to introduce if your editor auto-indents inconsistently) produces a parse error that can be confusing to track down.
- Indentation depth changes meaning. Move a key two spaces to the left or right, and it can silently become a sibling of a different parent. JSON's braces make this kind of mistake much harder to make invisibly.
Converting between them
In practice, you often need both: a human edits a YAML config, but the application that consumes it wants JSON, or an API returns JSON that you want to review as readable YAML. Since YAML is a superset of most of JSON's structure, converting between the two is usually mechanical — you're not losing information for typical configs, though YAML-only features like comments and anchors don't have a JSON equivalent and get dropped in a YAML-to-JSON conversion.
A simple rule of thumb
If a human is going to open the file in a text editor and change values by hand, lean toward YAML. If a program is going to generate it, send it over a network, or parse it thousands of times a second, lean toward JSON. Most real systems end up using both, each where it fits best — and that's a perfectly reasonable outcome.