Skip to content
d.devtul.fun
中文
Data formats · 2026-09-15

JSON or YAML: which one, and when

Write the same configuration in both formats and the difference speaks for itself:

{
  "name": "devtul",
  "port": 8080,
  "features": ["json", "yaml"],
  "database": { "host": "localhost", "ssl": true }
}
name: devtul
port: 8080
features:
  - json
  - yaml
database:
  host: localhost
  ssl: true

YAML drops the quotes, the commas and the braces. The price is that it is extremely sensitive to indentation.

Where JSON wins

  • No ambiguity. The grammar is small enough to state in a few hundred words, every language ships a parser, and no implementation disagrees with another.
  • Forgiving about whitespace. Minified to one line or spread over fifty, the meaning is identical. Merge conflicts are also easy to read.
  • Fast to parse. Nearly every language has a native or accelerated implementation.

The downsides: it is verbose to write, it has no comments, and multi-line strings are awkward.

Where YAML wins

  • It reads cleanly. In deeply nested configuration the eye moves through YAML much faster.
  • Comments. This matters more than it sounds — coming back six months later, you can still see why a setting was chosen.
  • Multi-line strings. | preserves line breaks and > folds them, which is invaluable for embedded scripts or certificates.
  • Anchors and aliases. Define a block with &name and reuse it with *name instead of repeating yourself.

Where YAML bites

YAML's expressiveness is both its strength and the source of its problems.

1. Bad indentation is a syntax error

Spaces or tabs, and how many, must be consistent throughout the file. An editor that renders a tab as four columns while storing \t produces the classic "looks aligned, fails to parse" situation.

2. Implicit type conversion

This one does the most damage:

country: NO     # not the string "NO" — the boolean false
version: 1.20   # not the string "1.20" — the number 1.2
time: 12:30     # parsed as 750 (sexagesimal)
yes_no: yes     # the boolean true

Country codes, version numbers, time strings — unquoted, they are silently turned into something else. The rule that saves you is simply quote anything you are unsure about.

3. Parsers do not agree on the edges

The YAML specification is large, and implementations in different languages cover different amounts of it. Some edge-case documents parse in one and fail in another.

Choosing

SituationUseWhy
API requests and responsesJSONUnambiguous, fast, consistent ecosystem
Kubernetes / CI pipeline configYAMLAlready the de facto standard, and comments are needed
Data interchange and storageJSONTypes are explicit; nothing gets guessed
Configuration humans edit oftenYAMLReadability and comments matter more
Lots of repeated blocksYAMLAnchors remove a great deal of duplication

A pragmatic middle ground: store JSON internally, hand people YAML with a validation step in front of it. Plenty of toolchains work exactly that way, converting YAML to JSON at build time before passing it downstream.

To move between the two, the JSON ⇄ YAML converter does it in either direction. Afterwards, glance at your numbers and booleans — version fields especially — to make sure nothing changed type behind your back.

Keep reading