Skip to content
100% in your browser. Nothing you paste is uploaded — all processing runs locally. Read more →

JSON vs YAML

On this page
  1. At a glance
  2. Same data, both formats
  3. Where JSON wins
  4. Where YAML wins
  5. YAML’s gotchas
    1. The Norway problem
    2. Indentation matters
    3. null has many spellings
    4. Duplicate keys are silently overwritten
  6. Performance
  7. When to use which
  8. Hybrid: TOML
  9. Conversion
  10. Common mistakes
  11. Try the tools

TL;DR. JSON for APIs and data interchange. YAML for human-edited configuration. Both can represent the same data, but their design priorities are opposite — JSON optimizes for parser simplicity, YAML for human writability.

At a glance

JSONYAML
SpecRFC 8259 (2017)YAML 1.2.2 (2021)
ReadabilityOKbetter
Writability (by humans)clunkyexcellent
Parser simplicitytrivialcomplex
Commentsnoyes (#)
Trailing commasnon/a
Multi-document supportnoyes (---)
Anchors / aliases (refs)noyes (& / *)
Tab vs space sensitivitynonetabs forbidden
Common useAPIs, logs, web datak8s, GitHub Actions, Hugo front matter
Performancefastslow (relative)

Same data, both formats

JSON:

{
  "apiVersion": "v1",
  "kind": "ConfigMap",
  "metadata": {
    "name": "demo",
    "labels": {
      "env": "dev",
      "team": "platform"
    }
  },
  "data": {
    "LOG_LEVEL": "info",
    "FEATURE_X": "true"
  }
}

YAML:

apiVersion: v1
kind: ConfigMap
metadata:
  name: demo
  labels:
    env: dev
    team: platform
data:
  LOG_LEVEL: info
  FEATURE_X: "true"

Same content. The YAML version is shorter, has no quotes around most strings, and is clearly hand-editable. The JSON version is unambiguous and parses faster.

Where JSON wins

Where YAML wins

YAML’s gotchas

YAML’s flexibility comes with footguns. The infamous ones:

The Norway problem

countries:
  - GB
  - NO          # ← parses as boolean false in YAML 1.1
  - FR

YAML 1.1 (still used by many parsers) treated NO, OFF, Y, N, YES, etc. as booleans. The fix: quote string values that look like booleans:

countries:
  - GB
  - "NO"
  - FR

YAML 1.2 narrowed this — only true/false are booleans. But many parsers (PyYAML’s default loader, snakeyaml) still default to 1.1 behavior.

Indentation matters

foo:
  bar: 1     # 2-space indent
   baz: 2    # 3-space — ERROR

Tabs are typically forbidden. Mixing tabs and spaces is a runtime error in most parsers.

null has many spellings

a:           # null
b: ~         # null
c: null      # null
d: Null      # null in 1.1, string in 1.2

Duplicate keys are silently overwritten

foo: 1
foo: 2       # most parsers: foo = 2, no error

JSON has the same issue, but YAML is used more in human-edited config where dupes are easier to introduce.

Performance

JSON parsing is roughly 5–10× faster than YAML in most languages. For a 1 MB config file:

Doesn’t matter for human-edited config (you parse it once at startup). Matters a lot for high-throughput data interchange.

When to use which

Is this a wire format between systems?
└── JSON

Is this human-edited configuration?
└── YAML

Is this a log line?
└── JSON (single-line, parseable)

Is this a Kubernetes / Helm / Ansible / GitHub Actions file?
└── YAML (no choice — those tools require it)

Is this OpenAPI / Swagger?
└── Either is accepted; YAML is more readable to hand-edit

Is this app state in a database?
└── JSON (or JSONB if you use Postgres)

Is this front matter (Hugo, Jekyll, Astro)?
└── YAML by default; JSON is also accepted

Are you not sure?
└── Default to JSON unless humans will hand-edit it

Hybrid: TOML

For human-edited config that wants JSON’s strictness without YAML’s whitespace sensitivity, TOML is the third option. It’s used by Cargo (Rust), Poetry (Python), and Hugo. Comments, types, no significant whitespace.

For most teams, picking JSON or YAML is enough — TOML is a niche addition.

Conversion

YAML → JSON is lossless for the data types JSON supports (objects, arrays, strings, numbers, booleans, null). YAML’s anchors/aliases get expanded; multi-document files become an array.

JSON → YAML is always lossless. Use the JSON → YAML converter on this site, or:

# yq (Go)
yq -o=yaml eval . data.json

# Python
python3 -c 'import json,yaml,sys; print(yaml.safe_dump(json.load(sys.stdin)))' < data.json

Common mistakes

Try the tools