JSON vs YAML
JSON and YAML describe the same data model. The differences are in what YAML adds on top, and in how each format fails when you get it wrong.
They describe the same thing
Both formats represent the same data model: mappings of keys to values, ordered
sequences, and scalar values. Anything expressible in one is expressible in the other.
YAML 1.2 is defined as a strict superset of JSON, which means every valid JSON document
is also a valid YAML document. You can rename a .json file to
.yaml and a YAML parser will read it.
The reverse is not true, and the gap is where all the interesting differences live.
The differences that matter
| Feature | JSON | YAML |
|---|---|---|
| Comments | None | # to end of line |
| Structure marked by | Braces and brackets | Indentation |
| Quotes on strings | Always required | Optional when unambiguous |
| Trailing commas | Invalid | Not applicable |
| Reuse of a value | Copy it | Anchors and aliases |
| Multiple documents per file | No | Yes, separated by --- |
| Multi-line strings | Escaped \n | Block scalars |
| Spec size | About 20 pages | About 80 pages |
| Parse speed | Fast, built into every browser | Slower, needs a library |
| Failure mode | Loud — it fails to parse | Quiet — it parses as the wrong thing |
The difference in failure mode is the real trade-off. JSON's strictness means mistakes surface immediately, at the parser. YAML's flexibility means a mistake can produce a valid document with a different meaning, which surfaces in production instead.
Choosing between them
Use JSON when
- The data crosses a network boundary. Every language parses it, fast, without a dependency.
- Machines write it and machines read it.
- You want unambiguous types with no inference.
- You need to embed the data in a single line — a log entry, an environment variable, a shell argument.
Use YAML when
- Humans write the file and other humans review it in a pull request.
- The file needs comments explaining why a value is what it is.
- The ecosystem expects it: Kubernetes, Ansible, Docker Compose, GitHub Actions, GitLab CI, OpenAPI. For manifests specifically, the Kubernetes converter checks the document as well as translating it.
- Repeated blocks would otherwise be copy-pasted, and anchors can capture the relationship.
The practical answer in most projects is both. YAML is the source of truth in the repository, where people read and edit it. JSON is what the build step emits and what services actually consume. That is the shape of the two converters here: JSON to YAML when you are moving a generated document somewhere a person will maintain it, and YAML to JSON when it is heading into a program.
The cost of YAML's flexibility
YAML's convenience features each carry a sharp edge.
Type inference
Unquoted scalars are inspected and converted, which the
YAML validator will show you by printing the parsed
result. 1.10 becomes 1.1.
0755 may become octal 493. NO may become false. Quoting is the
defence and it costs nothing.
Significant whitespace
A single misplaced space changes structure rather than raising an error. A key indented two spaces too far becomes a child of its sibling. The document is valid; the meaning is wrong.
Attack surface
Some YAML libraries can construct arbitrary objects from tags in the document. This
is the vulnerability behind years of yaml.load() advisories in Python. Use
safe_load and equivalents on any input you did not write yourself.
None of this makes YAML a bad format. It makes it a format with more ways to be subtly wrong, which is a reasonable price for comments and readability in files people maintain by hand.