The Same Data, Two Notations
JSON (JavaScript Object Notation) and YAML (YAML Ain't Markup Language) both model the same building blocks: mappings (objects), sequences (arrays), and scalars (strings, numbers, booleans, null). In fact, YAML is a superset of JSON — most valid JSON is also valid YAML. The difference is style: JSON leans on explicit punctuation, while YAML leans on indentation and whitespace to convey structure.
Here is the same record written both ways:
// JSON
{
"name": "Formatly",
"tools": ["json", "yaml", "csv"],
"private": true,
"limits": null
}// YAML
name: Formatly
tools:
- json
- yaml
- csv
private: true
limits: nullBoth encode an object with a string, an array of three strings, a boolean, and a null. YAML drops the braces, brackets, and most quotes; JSON keeps them.
Syntax Differences That Matter
- Structure: JSON uses
{}for objects and[]for arrays. YAML uses indentation for nesting and a leading-for list items. (YAML also supports inline "flow" style —tools: [json, yaml, csv]— which looks JSON-like.) - Quotes: JSON requires double quotes around every key and every string value. YAML usually lets you omit quotes, only needing them for ambiguous values.
- Comments: YAML supports comments with
#; JSON has no comment syntax at all. This alone makes YAML attractive for hand-edited config files. - Trailing commas: Standard JSON forbids a trailing comma after the last element. YAML has no separating commas in block style, so the problem disappears.
- Verbosity: JSON is more compact on a single line and tends to be smaller over the wire; YAML is more vertical and easier to scan in a diff.
Features YAML Has and JSON Lacks
Anchors and aliases let you define a block once and reuse it, avoiding repetition:
defaults: &defaults
retries: 3
timeout: 30
staging:
<<: *defaults
url: https://staging.example.comHere &defaults names a node, *defaults references it, and <<: merges it. JSON has no equivalent — you would copy the values by hand.
Multi-line strings are far cleaner in YAML. The literal block scalar | preserves newlines, and the folded scalar > joins wrapped lines with spaces:
script: |
echo "line one"
echo "line two"In JSON the same value would be one long string with explicit \n escapes: "echo \"line one\"\necho \"line two\"\n".
Gotchas: The Famous "Norway Problem"
YAML's friendly, quote-optional scalars are also its biggest footgun. Older YAML parsers (the YAML 1.1 spec) interpret a long list of bare words as booleans: yes, no, true, false, on, and off. The classic example is a list of country codes:
countries:
- NO # Norway → parses as the boolean false!
- SE
- GBBecause NO can be read as "no", it may silently become false. The fix is to quote it: "NO". Related traps include version numbers like 1.20 losing the trailing zero (it becomes the number 1.2), and values like 10:30 being read as a sexagesimal number rather than a time string. The newer YAML 1.2 core schema removes the yes/no/on/off aliases, but many real-world tools still run on 1.1 behavior, so quote anything that could be misread.
The other recurring YAML pain is indentation: tabs are forbidden, and a single misaligned space changes the structure or breaks parsing. JSON avoids both problems because its brackets make boundaries explicit and its type rules are strict — a string is always quoted, so "NO" is never a boolean.
When to Use Each
- Reach for JSON for machine-to-machine interchange: REST and GraphQL API payloads, web tokens, package manifests (
package.json), and anything parsed by code at high volume. Its strictness and ubiquity make it the safe default for data on the wire. - Reach for YAML for human-authored configuration where comments and readability pay off: Kubernetes manifests, GitHub Actions and other CI pipelines, Docker Compose, Ansible playbooks, and app config files.
Converting Between Them with Formatly
You rarely have to rewrite by hand. Formatly's JSON to YAML Converter turns either format into the other. Paste your data, set the Direction toggle to JSON → YAML or YAML → JSON, and read the result; the Swap button flips direction and feeds the output back as new input. JSON output is pretty-printed with two-space indentation and syntax highlighting, and invalid input returns a precise parser error so you can fix it.
Because the converter runs entirely in your browser using JavaScript, your data is never uploaded, transmitted, or stored on any server — it works offline once the page has loaded, which matters when your config holds secrets, hostnames, or other sensitive values.