← All articles

JSON vs YAML: Differences and When to Use Each

JSON vs YAML compared: syntax, types, comments, and gotchas like the Norway problem. YAML is a JSON superset — here's when to use each and how to convert.

JSON and YAML solve the same problem — representing structured data as text — but they make opposite trade-offs. JSON optimises for unambiguous machine parsing; YAML optimises for human authoring. Since YAML 1.2, every valid JSON document is also valid YAML. This guide compares their syntax, types, and features, and explains when to reach for each.

The Short Answer

Use JSON for data exchanged between programs — API responses, message payloads, anything machine-generated. Use YAML for files humans write and edit by hand — CI pipelines, Kubernetes manifests, application config — where comments and readability matter.

Side-by-Side Syntax

The same data in both formats:

# YAML
service: api
replicas: 3
ports:
  - 8080
  - 8443
env:
  LOG_LEVEL: info
  DEBUG: false
// JSON
{
  "service": "api",
  "replicas": 3,
  "ports": [8080, 8443],
  "env": {
    "LOG_LEVEL": "info",
    "DEBUG": false
  }
}

YAML uses indentation instead of braces and brackets, drops most quotes, and allows comments. JSON is more verbose but has no significant whitespace, which makes it far easier to parse and generate reliably.

YAML Is a Superset of JSON

Since YAML 1.2 (2009), YAML is a strict superset of JSON — every valid JSON document is valid YAML, because YAML adopted JSON's "flow" syntax directly. That's why you can paste JSON into a YAML file and it just works. For the history behind this, see YAML 1.2 and JSON Compatibility.

# This is valid YAML — it's also valid JSON
{"service": "api", "replicas": 3}

Feature Comparison

FeatureJSONYAML
CommentsNoYes (#)
Trailing commasNoN/A (no commas in block style)
Multi-line stringsEscaped \n onlyNative (| and >)
Anchors / referencesNoYes (& / *)
Multiple documents per fileNoYes (--- separator)
Significant whitespaceNoYes (indentation matters)
Parsing complexityTrivialComplex
Best forMachine data exchangeHuman-edited config

Type Handling: YAML's Sharp Edges

YAML's eagerness to infer types causes surprises that JSON's explicit quoting avoids:

# The "Norway problem" — these become booleans in YAML 1.1 parsers
countries:
  - NO   # → false (!)
  - SE
  - true # → boolean, not the string "true"

version: 1.20   # → the number 1.2, trailing zero lost
zip: 01234      # → 668 (parsed as octal) in some parsers

JSON has none of these ambiguities: "NO" is always the string NO, and "01234" is always that string. When a YAML value must be a string, quote it explicitly.

Where TOML and JSON5 Fit In

Two other common "human-friendly" config formats come up in the same conversation:

  • TOML — section/key style, designed for hand-edited app configuration (Cargo, Poetry, Hugo). Stricter than YAML, no significant indentation, native typed values (datetime, integer, float, array, inline table). Best when the data is mostly flat tables.
  • JSON5 — JSON with developer-friendly relaxations: comments, trailing commas, unquoted keys, single quotes, multi-line strings. Not a standard JSON parser will accept; you opt in with a JSON5 library (or a JSONC parser for the comment + trailing-comma subset, e.g. tsconfig.json).

Rough fit: JSON for machine exchange, YAML for deeply nested human-edited config, TOML for flat app/tool config, JSON5/JSONC when you want JSON-with-comments for editor configs without adopting YAML's whitespace rules.

When to Use Which

  • Use JSON for: REST/GraphQL APIs, message queues, browser localStorage, package.json, anything generated or consumed by code.
  • Use YAML for: GitHub Actions / GitLab CI, Kubernetes and Docker Compose, Ansible playbooks, app config that humans edit and want to comment.

A common pattern: author config in YAML for readability, then convert to JSON at build or load time so your application only ever parses JSON.

Converting Between JSON and YAML

# Python — YAML to JSON
import yaml, json
data = yaml.safe_load(open('config.yaml'))
print(json.dumps(data, indent=2))

# Command line with yq
yq -o=json '.' config.yaml      # YAML → JSON
yq -P '.' config.json           # JSON → YAML

Or convert instantly in your browser with fixjson's YAML ⇄ JSON converter — paste YAML, get JSON (or the reverse), with no data sent to any server.

Frequently Asked Questions

Is YAML better than JSON?

Neither is "better" — they're tuned for different jobs. YAML is better for human-edited config (comments, readability); JSON is better for machine data exchange (simple, fast, unambiguous parsing).

Is JSON valid YAML?

Yes. Since YAML 1.2, YAML is a strict superset of JSON, so any valid JSON document is also valid YAML. The reverse is not true — most YAML is not valid JSON.

Why does YAML turn "NO" into false?

YAML infers types from unquoted scalars, and some parsers read NO, yes, on, off as booleans (the "Norway problem"). Quote the value ("NO") to force a string. JSON avoids this entirely with mandatory quotes.

Should I use YAML or JSON for config files?

Use YAML if humans edit the file and benefit from comments and multi-line strings; use JSON if it's generated or consumed by tooling. Many teams write YAML and convert to JSON at load time.

Convert and Validate in Your Browser