A practical comparison of YAML and JSON — syntax differences, pros and cons, and when each format is the right choice for config files and APIs.
YAML and JSON are both data serialization formats, but they serve different purposes. Picking the wrong one leads to headaches — YAML's flexibility can cause subtle bugs, while JSON's strictness can make config files painful to maintain.
The same data in both formats:
# YAML
name: HeoLab
version: 1.0.0
features:
- json-formatter
- jwt-decoder
- base64
database:
host: localhost
port: 5432
ssl: true
description: >
This is a long description that
spans multiple lines.
{
"name": "HeoLab",
"version": "1.0.0",
"features": ["json-formatter", "jwt-decoder", "base64"],
"database": {
"host": "localhost",
"port": 5432,
"ssl": true
},
"description": "This is a long description that spans multiple lines."
}
| Feature | YAML | JSON |
|---|---|---|
| Comments | Yes (#) | No |
| Syntax verbosity | Low (no quotes, braces) | High |
| Multi-line strings | Yes | Escaped only |
| Type coercion | Implicit (danger!) | Explicit |
| Machine-readable | Harder to parse | Easier |
| Whitespace sensitivity | Yes (indentation) | No |
| Valid subset | JSON is valid YAML | No |
| Human writable | Easier | Harder |
YAML's implicit typing is its most dangerous feature:
# These become booleans:
enabled: yes # true
disabled: no # false
flag: on # true
feature: off # false
# This becomes an integer:
version: 1.10 # 1.1 (not the string '1.10'!)
# Country codes become booleans in YAML 1.1:
norway: NO # false! (the famous Norway problem)
canada: CA # 'CA' (ok, it's a string)
# Fix: always quote strings
norway: "NO"
version: "1.10"
The Norway problem caught many developers — in YAML 1.1, NO, YES, ON, OFF are all boolean values.
# Literal block scalar (|) — preserves newlines
message: |
Hello,
World!
# => "Hello,\nWorld!\n"
# Folded block scalar (>) — newlines become spaces
description: >
This is a very long
description that wraps.
# => "This is a very long description that wraps.\n"
# Inline (use \n for newlines)
message: "Hello,\nWorld!"
YAML shines for human-written configuration:
docker-compose.yml).github/workflows/*.yml)JSON is better for machine-generated or API data:
package.json, tsconfig.json, eslint.json// JSON to YAML (Node.js)
const yaml = require('js-yaml');
const jsonData = { name: 'test', value: 42 };
const yamlStr = yaml.dump(jsonData);
// YAML to JSON
const data = yaml.load(yamlStr);
const jsonStr = JSON.stringify(data, null, 2);
Use the YAML ⇄ JSON Converter tool to convert between formats instantly in your browser — useful for converting API responses to config files or vice versa.