JSON and YAML are two ways to write the same thing: structured data made of objects, lists, strings, numbers and booleans. JSON wraps it in braces and commas; YAML uses indentation and line breaks. Because they model identical structures, you can convert between them losslessly — but there are a few traps worth knowing.
We measured this ourselves — and caught our own mistake doing it. Running
{"service":"api","ports":[80,443],"env":{"DEBUG":"false","RETRIES":3}}through our JSON to YAML converter returns:service: api ports: - 80 - 443 env: DEBUG: 'false' RETRIES: 3
DEBUGkeeps its quotes whileRETRIESdoes not, and that is the whole point: in YAML an unquotedfalseis a boolean, so dropping the quotes would silently change the type. Note the quotes are single. Our own example page said"false"with double quotes until a verification script compared the published text against what the tool really outputs and flagged the mismatch. Small difference, but a documentation page that does not match its own tool is worse than no page.
The same data, two styles
JSON:
{ "name": "Yunknow", "tags": ["free", "fast"], "active": true }
YAML:
name: Yunknow
tags:
- free
- fast
active: true
Same data, different clothes. YAML drops the punctuation and leans on indentation, which is why config files love it.
Nesting is where the two notations diverge most visibly. This JSON — a list and a nested object — through our own JSON ↔ YAML converter:
list:
- 1
- 2
deep:
k: 'yes'
Braces and brackets became indentation, and the list items became - entries. Nothing about the data changed; the delimiters moved into the whitespace. That is simultaneously why YAML is easier to read and why it is easier to break — a misplaced space is a structural edit.
When to use which
- JSON — APIs,
package.json, anything a program reads or writes automatically. Strict, unambiguous, universally supported. - YAML — config you edit by hand: Docker Compose, Kubernetes, GitHub Actions, CI pipelines. Easier to read, supports comments.
A common workflow is to write config in YAML and have tools consume it as JSON.
That difference decides the choice far more often than syntax preference does. JSON has exactly six value types and no type inference, so v: 'true' port: '8080' simply cannot happen there: a quoted string stays a string with no rule to rescue it from. YAML infers, which is what makes it pleasant for hand-written configuration and risky for machine-generated data.
Gotchas that trip people up
- Indentation is significant in YAML. Mixing tabs and spaces, or getting the depth wrong, changes the meaning or breaks the parse. Always indent with spaces.
- Comments vanish going to JSON. JSON has no comment syntax, so
# notelines are lost when you convert YAML → JSON. That’s expected, not a bug. - The “Norway problem.” In older YAML, unquoted
no,yes,on,offbecome booleans — so the country codeNOcan turn intofalse. Quote strings that look like booleans. - Anchors get expanded. YAML’s
&anchor/*refreuse is flattened into plain data when converting to JSON.
And here is the gotcha that costs real time. Our converter surfaces it as quotes you did not ask for:
name: x
'on': true
'n': null
on and n came back quoted. In YAML 1.1 the bare words on, off, y, n, yes and no are booleans, so an unquoted key on would parse as true. The mirror case is a value that has to stay a string:
v: 'true'
port: '8080'
Both kept their quotes, because dropping them would turn a string into a boolean and a port number into an integer. This is the famous “Norway problem” — NO read as false — and it is a property of YAML itself, not of any one converter.
Feature comparison
| Feature | JSON | YAML |
|---|---|---|
| Comments | No | Yes (#) |
| Trailing commas | Not allowed | Not applicable |
| Human readability | Good | Better for deep nesting |
| Parsing speed | Faster | Slower |
| Multi-line strings | Escaped \n only | Block scalars |
| Multiple docs per file | No | Yes (--- separators) |
One underused YAML feature is block scalars for long text — a literal block keeps line breaks, a folded block joins them into one line:
description: |
Line one stays a line.
Line two stays a line.
summary: >
This wraps across
several source lines
but becomes one line.
Frequently asked questions
Is YAML a superset of JSON? Effectively yes. As of YAML 1.2, any valid JSON document is also valid YAML, so a YAML parser can read JSON directly. The reverse isn’t true — JSON can’t parse YAML’s indentation syntax.
Which should an API return? JSON, almost always — it’s faster to parse, unambiguous and supported everywhere. Keep YAML for files humans edit by hand.
Where did my comments go after converting? They’re dropped, because JSON has no comment syntax. If you need to keep notes, add a real "_comment" key instead. For a deeper look at the format itself, see what is JSON.
Convert safely, in your browser
The JSON ⇄ YAML converter turns one into the other and checks the syntax as it goes — pointing to the exact error if something is off. It runs entirely in your browser, so even private config never leaves your device.
Related tools
- To beautify, minify or validate JSON, use the JSON formatter.
- To move tabular JSON into a spreadsheet, use JSON ⇄ CSV ⇄ Excel.