Skip to content
Appachi Tools

JSON vs. YAML: Same Data, Two Philosophies

They describe identical structures, but JSON and YAML optimize for opposite audiences — one for machines, one for humans. That difference explains both YAML's popularity in config files and its most notorious gotcha.

JSON and YAML can describe exactly the same data — any valid JSON document is also valid YAML, in fact — but they were designed with opposite priorities, and that difference explains almost everything about where each one ends up being used.

The same object, two ways

{
  "name": "appachi-tools",
  "port": 8080,
  "features": ["formatters", "encoders", "generators"],
  "debug": false
}
name: appachi-tools
port: 8080
features:
  - formatters
  - encoders
  - generators
debug: false

Identical data. JSON leans on explicit punctuation — every object wrapped in {}, every array in [], every string quoted. YAML leans on indentation and largely drops the punctuation, trading explicitness for readability.

Why the difference exists

JSON was designed to be trivial for a machine to parse and generate — it's a strict, tightly-specified subset of JavaScript's object literal syntax, standardized in the 2000s, and its whole appeal is that there's essentially one way to write anything, so tooling around it is simple and fast.

YAML ("YAML Ain't Markup Language") was designed for the opposite priority: to be pleasant for a human to write and read by hand. That's why it supports comments (# like this) — a feature JSON has no syntax for at all — and why config files, CI pipelines and Kubernetes manifests overwhelmingly favor it: those are files people actually hand-edit and review, not just machine-generated payloads passed between services.

Where each one wins

JSON wins for API payloads and anywhere a machine is both producing and consuming the data — its simplicity means near-zero parsing ambiguity, and virtually every language has a fast, standard-library JSON parser.

YAML wins for anything a human maintains directly — Kubernetes manifests, CI/CD pipeline definitions, application config — where the ability to add a comment explaining why a value is set the way it is, and to read the structure without a wall of braces, is worth more than machine-parsing simplicity.

The gotcha YAML is (in)famous for

YAML's indentation-based structure means a single misplaced space can silently change a document's meaning instead of throwing an obvious error the way a missing } in JSON usually would. But the more notorious gotcha is type coercion: YAML tries to be helpful by inferring types from unquoted values, and its rules for what counts as a boolean are wider than most people expect.

This produced what's commonly called the Norway problem: in YAML 1.1 (the version many parsers still implement), the unquoted value NO — the two-letter ISO country code for Norway — parses as the boolean false, not the string "NO". A country list with unquoted codes can silently lose Norway. The same 1.1 spec treats yes, no, on, off, true and false (in various cases) all as booleans, which has bitten plenty of config files where someone wrote a version string like 3.10 and had it parsed as the number 3.1, or a value like on meant as a literal string and got a boolean instead.

The fix is simple once you know to look for it: quote any value that could be misread"NO", "on", "3.10" — especially country codes, version strings, and anything that overlaps with YAML's boolean/null keywords. A validating converter (like the one linked below) will catch this kind of misparse before it reaches a live config.

Converting between them

Because any JSON document has a direct YAML equivalent, JSON → YAML is always lossless. The reverse isn't guaranteed — YAML supports features with no JSON equivalent (comments, anchors and aliases for reusing a block, multi-document files separated by ---), all of which get dropped or flattened when converting down to JSON. Worth knowing before you round-trip a hand-written YAML config through JSON and back.

Convert between JSON and YAML — validated both directions, entirely in your browser.