When setting up a new project, you'll often face a choice: JSON or YAML for configuration? Both formats can represent the same data, but they have different strengths. Let's compare them.
JSON and YAML Origins
JSON (JavaScript Object Notation) emerged in the early 2000s as a lightweight alternative to XML. It's a subset of JavaScript and prioritizes simplicity and machine-readability.
YAML (YAML Ain't Markup Language) was created in 2001 with a focus on human readability. It's a superset of JSON—meaning any valid JSON is also valid YAML.
Syntax Comparison
The same data in both formats:
JSON:
{
"server": {
"host": "localhost",
"port": 8080,
"ssl": true
},
"database": {
"connection": "postgres://localhost:5432/mydb",
"pool_size": 10
},
"allowed_origins": [
"https://example.com",
"https://api.example.com"
]
}
YAML:
server:
host: localhost
port: 8080
ssl: true
database:
connection: postgres://localhost:5432/mydb
pool_size: 10
allowed_origins:
- https://example.com
- https://api.example.com
Key differences:
- YAML uses indentation instead of braces
- YAML doesn't require quotes around most strings
- YAML uses
:for key-value pairs (no quotes on keys) - YAML arrays use
-instead of[brackets]
Readability Differences
YAML is generally more readable for humans:
Nested structure in JSON:
{
"logging": {
"level": "info",
"format": "json",
"outputs": [
{"type": "console"},
{"type": "file", "path": "/var/log/app.log"}
]
}
}
Same in YAML:
logging:
level: info
format: json
outputs:
- type: console
- type: file
path: /var/log/app.log
The YAML version has less visual noise—no quotes, braces, or commas cluttering the view.
Comments: YAML Yes, JSON No
One of YAML's biggest advantages:
# Database configuration
database:
host: localhost # Use 'db' in production
port: 5432
# pool_size: 10 # Uncomment for production
JSON has no comment syntax. People work around this with:
{
"_comment": "Database configuration",
"database": {
"host": "localhost"
}
}
But these fake comments become part of the data and may cause issues.
When to Use JSON
Choose JSON when:
1. Working with APIs
APIs universally use JSON. It's the standard:
{"status": "success", "data": {"id": 123}}
2. Programmatic generation
JSON is easier to generate from code:
const config = JSON.stringify(settings, null, 2);
3. Strict validation needed
JSON's strictness catches errors early—no ambiguity.
4. Cross-platform data exchange
Every language has robust JSON support.
5. Browser environments
JavaScript natively parses JSON with JSON.parse().
When to Use YAML
Choose YAML when:
1. Human-edited configuration
YAML's readability shines for config files:
# Application settings
app:
name: My App
debug: true
features:
- authentication
- notifications
2. DevOps and infrastructure
Kubernetes, Docker Compose, Ansible, and many CI/CD tools use YAML:
# docker-compose.yml
services:
web:
image: nginx
ports:
- "80:80"
3. Documentation is needed
Comments let you explain configuration inline:
timeout: 30 # seconds, increase for slow networks
4. Multi-document files
YAML supports multiple documents in one file:
---
# Development config
environment: development
debug: true
---
# Production config
environment: production
debug: false
YAML Gotchas: The Norway Problem
YAML's flexibility creates surprising behaviors:
Boolean coercion
YAML interprets certain words as booleans:
country: Norway # String ✓
country: NO # Boolean false! ✗
The two-letter country code for Norway (NO) becomes false. Same with:
yes,no→true,falseon,off→true,falsey,n→true,false
Fix: Quote ambiguous strings:
country: "NO"
Number coercion
version: 1.0 # Number 1 (not "1.0")
version: "1.0" # String "1.0" ✓
zipcode: 01234 # Octal number! (668 in decimal)
zipcode: "01234" # String ✓
Colons in strings
title: Hello: World # Parse error!
title: "Hello: World" # OK ✓
Multi-line strings
YAML has multiple ways to handle multi-line strings:
# Literal block (preserves newlines)
description: |
Line 1
Line 2
# Folded block (joins lines)
description: >
This is a long
description that
becomes one line.
Converting Between Formats
YAML to JSON
Python:
import yaml
import json
with open('config.yaml') as f:
data = yaml.safe_load(f)
print(json.dumps(data, indent=2))
Command line (with yq):
yq -o=json config.yaml
JSON to YAML
Python:
import yaml
import json
with open('config.json') as f:
data = json.load(f)
print(yaml.dump(data, default_flow_style=False))
Best Practices for Config Files
JSON config files
{
"server": {
"host": "0.0.0.0",
"port": 3000
}
}
- Always pretty-print for readability
- Use a JSON schema for validation
- Consider JSON5 or JSONC for comments
YAML config files
# Application configuration
# See docs/configuration.md for details
server:
host: "0.0.0.0" # Quote strings that could be ambiguous
port: 3000
# Timeout values in seconds
timeouts:
connect: 5
read: 30
- Quote strings that might be misinterpreted
- Use comments to explain non-obvious settings
- Be consistent with indentation (2 spaces is common)
- Validate with a schema (like JSON Schema, which works for YAML too)
Feature Comparison
| Feature | JSON | YAML |
|---|---|---|
| Human readable | Good | Better |
| Machine readable | Excellent | Good |
| Comments | No | Yes |
| Multi-document | No | Yes |
| Strict syntax | Yes | No (more flexible) |
| Learning curve | Low | Medium |
| Error messages | Clear | Sometimes cryptic |
| Whitespace significant | No | Yes |
| Native browser support | Yes | No |
Summary
- JSON: Use for APIs, data exchange, and when you need strict validation
- YAML: Use for human-edited configuration, DevOps tools, and when you need comments
Neither is universally "better"—they serve different purposes. Many projects use both: YAML for configuration, JSON for API responses.
When in doubt:
- For data interchange → JSON
- For configuration → YAML (but be aware of gotchas!)
Need to convert between formats? Try our JSON to YAML Converter!