data · 7 min read

JSON, YAML or TOML — which to use for what

They store the same shapes and they are not competing. One is for machines talking to machines; the other two are for people editing a file.

All three describe the same thing: nested maps and lists of strings, numbers and booleans. Converting between them is mechanical. So the choice is not about capability, it is about who is going to be typing.

JSON is for transmission

It was designed to be produced and consumed by programs, and everything about it follows from that. The syntax is strict, so there is exactly one way to read any document. Braces and brackets mean whitespace does not matter. Every parser agrees.

The strictness is a feature in transit and a burden in a file someone maintains. No comments. No trailing commas — the one that costs the most, because adding a line to the end of a list means editing the line above it. Keys must be double-quoted. Nothing is forgiving.

For an API response, a log line, or anything a machine writes, that is exactly right.

YAML is for editing

Indentation replaces braces, quotes are usually optional, comments are allowed, and long strings can be written across several lines without escaping. A YAML file reads like a document, which is why it took over configuration.

Everything that makes it pleasant also makes it easy to get subtly wrong. Indentation is significant, so one stray space changes the structure. A tab character is a syntax error, and tabs are invisible. The spec is famously large, and parsers differ at the edges.

The type inference that keeps catching people

This is the specific thing worth knowing before you write any YAML.

An unquoted value is interpreted rather than taken literally. Under YAML 1.1 — still what many deployed parsers implement — NO becomes the boolean false, which memorably turns Norway's country code into false. ON, OFF, YES and Y are booleans too.

Numbers are worse. A version written as 1.20 becomes the number 1.2 and loses its trailing zero. A value beginning with a zero may be read as octal. Something like 6e2 — a plausible git hash prefix — becomes 600. A MAC address with colons can be read as a sexagesimal number.

The fix is one character: quote anything that is meant to be a string. It is worth doing by default rather than when you notice.

TOML is for configuration that is mostly flat

Comments, obvious syntax, no significant whitespace, and no surprise type inference — values mean what they say. For an application's settings file it is the easiest of the three to get right.

It becomes awkward with deep nesting, where the table-header syntax turns into long dotted names, and with long lists of objects. That is precisely where YAML stays readable, which is why deployment and pipeline configuration is YAML and package metadata is increasingly TOML.

How to choose

A machine writes it and a machine reads it — JSON. Fastest to parse, universally supported, no ambiguity.

A person edits it and it has real structure — YAML. Pipelines, deployments, anything with lists of steps.

A person edits it and it is mostly settings — TOML.

It has to be read by both — JSON, with the configuration generated from something else. Hand-maintaining JSON is where the missing comments hurt most.

Converting between them

The conversion is lossy in one direction and only one: comments do not survive. Converting YAML to JSON discards every explanatory note in the file, and converting back does not restore them.

That is worth stating because it is not obvious and it is irreversible. If a YAML file is documented — and a good one is — treat it as the source and generate the JSON, rather than round-tripping.

Converting is otherwise mechanical, and formatting a JSON document is worth doing before reading one — a minified response is a wall, and the same data indented is usually obvious.

The short version

JSON for transmission, YAML for structured configuration a person maintains, TOML for settings. Quote your YAML strings. And remember that converting away from YAML throws the comments away for good.

Questions

What is the difference between JSON and YAML?

JSON is a data interchange format: strict, unambiguous, no comments, and trivial for a machine to produce and parse. YAML is a configuration language: indentation instead of braces, comments allowed, and far more forgiving syntax — which is what makes it pleasant to edit and harder to get exactly right.

Is YAML a superset of JSON?

Since YAML 1.2, essentially yes — a valid JSON document is valid YAML, so a YAML parser will read your JSON. The reverse is not true, and the compatibility is easy to over-rely on because YAML 1.1 parsers are still widely deployed and differ in exactly the awkward places.

Why did YAML turn my value into true or a number?

YAML infers types from unquoted values. In older parsers the country code NO becomes the boolean false, ON and YES become true, a version like 1.20 loses its trailing zero, and a MAC address or a git hash can be read as a number in scientific notation. Quoting the value stops all of it.

Can I put comments in JSON?

No. The specification has no comment syntax, which is deliberate and is the single biggest reason JSON is unpleasant as a configuration format. JSON5 and JSONC add them and are not JSON, so anything consuming your file has to opt into them.

Should I use TOML instead?

For flat or lightly nested configuration, TOML is easier to get right than either — obvious syntax, comments, no significant whitespace, no surprise type inference. It gets awkward with deep nesting or long lists of objects, which is where YAML remains more readable.

Tools from this guide