YAML vs JSON: When to Use Each and Key Differences
A complete comparison of YAML and JSON โ syntax differences, YAML gotchas (the Norway problem!), and when each format is the right choice.
ToolNest Team
August 1, 2025
YAML vs JSON: Which Should You Use?
Both YAML and JSON are human-readable data serialization formats, but they serve different use cases well. The short answer: use JSON for APIs and machine-to-machine data; use YAML for configuration files that humans edit.
YAML Syntax Basics
YAML (YAML Ain't Markup Language) uses indentation to represent structure, making it more readable for complex configurations:
# YAML supports comments (JSON does not)
name: John Doe
age: 30
is_active: true
address:
street: 123 Main St
city: Austin
state: TX
tags:
- developer
- designer
profile_image: null
The Same Data in JSON
{
"name": "John Doe",
"age": 30,
"is_active": true,
"address": {
"street": "123 Main St",
"city": "Austin",
"state": "TX"
},
"tags": ["developer", "designer"],
"profile_image": null
}
YAML is more concise and allows comments. JSON uses more punctuation but is unambiguous.
Key Differences
| Feature | YAML | JSON |
|---|---|---|
| Comments | Supported (# comment) |
Not allowed |
| Syntax | Indentation-based | Brace/bracket-based |
| Strings | Quotes optional | Double quotes required |
| Verbosity | Less verbose | More verbose |
| Parsing speed | Slower | Faster |
| Specification complexity | Complex | Simple |
| Interoperability | Some language-specific quirks | Extremely consistent |
| Use in APIs | Rarely | Almost always |
| Use in config | Very common | Common |
YAML Superpowers
1. Comments โ The most requested JSON feature that doesn't exist. Essential for documenting configuration files.
2. Multi-line strings:
# Folded (newlines become spaces)
message: >
This is a very long message that
spans multiple lines but will be
joined into one line.
# Literal (preserves newlines)
script: |
#!/bin/bash
echo "Hello"
echo "World"
3. Anchors and aliases (DRY configuration):
defaults: &defaults
retry: 3
timeout: 30
development:
<<: *defaults
debug: true
production:
<<: *defaults
debug: false
*defaults is an alias that merges the defaults mapping. No duplication.
YAML Gotchas โ The Dangerous Parts
YAML's flexibility comes with surprising edge cases:
The Norway Problem:
countries:
- GB
- DE
- NO # This is parsed as boolean false!
- FR
In YAML 1.1 (used by many parsers), NO, YES, ON, OFF, TRUE, FALSE are all parsed as booleans. So the country code "NO" becomes false. Always quote ambiguous strings: "NO", "YES".
YAML 1.2 (newer) restricts booleans to only true and false, but many tools (including PyYAML and Ruby's YAML) still use 1.1 rules.
Date auto-parsing:
release_date: 2024-01-15 # Parsed as a date object, not a string!
version: "2024-01-15" # This stays a string
Octal numbers:
# YAML 1.1
file_permissions: 0755 # Parsed as octal = 493 decimal!
Implicit typing:
port: 8080 # Integer
port: "8080" # String
enabled: yes # Boolean (YAML 1.1)
version: 1.0 # Float (1.0), not string "1.0"
The fix: When in doubt, quote your values. "NO", "true", "1.0" are always strings.
When to Use YAML
- Kubernetes manifests โ The entire Kubernetes ecosystem uses YAML
- Docker Compose files โ
docker-compose.yml - GitHub Actions workflows โ
.github/workflows/*.yml - CI/CD pipelines โ GitLab CI, CircleCI, Travis CI
- Ansible playbooks โ Infrastructure automation
- Application configuration โ Rails config, Rails routes, Helm charts
- Documentation โ Front matter in Hugo, Jekyll, Gatsby
When to Use JSON
- REST APIs โ Request and response bodies; universally expected
- Configuration with strict typing requirements โ Ambiguity is dangerous
- Programmatic generation โ Easier to generate correctly from code
- Browser storage โ localStorage, IndexedDB
- NoSQL databases โ MongoDB, Firestore
- Package manifests โ
package.json,composer.json - When the audience is machines โ JSON parsing is faster and unambiguous
YAML in Docker Compose
version: "3.9"
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
environment:
- NODE_ENV=production
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: secret
The comment support and anchors in YAML make complex Docker Compose files much more manageable than equivalent JSON would be.
Use our free YAML Validator to check YAML syntax and our JSON to YAML converter to transform between formats.
Share this article