Other Resources

YAML vs JSON: When to Use Each Configuration Format

Every project needs configuration files. Some teams swear by JSON. Others insist on YAML. I've used both extensively across dozens of projects, and the "right" choice depends on your specific situation, team preferences, and use case. Here's what I've learned after years of working with both formats.

The YAML vs JSON debate generates surprising amounts of heat for something as mundane as data serialization formats. But the choice matters more than you might think – it affects maintainability, readability, error rates, and developer happiness.

JSON configuration example

JSON: The Universal Standard

JSON (JavaScript Object Notation) is everywhere. Every programming language can parse it natively or with a simple library. Browsers understand it. APIs use it. It's the lingua franca of data interchange on the modern web.

JSON's Strengths

  • Universal compatibility: Literally every language and platform supports it
  • Strict syntax: Unambiguous parsing, fewer edge cases
  • Machine-friendly: Easy to generate programmatically
  • Browser native: JavaScript's JSON.parse() and JSON.stringify() built-in
  • Validation tools: JSON Schema provides robust validation
  • Streaming support: Can parse large files incrementally

When JSON Wins

Use JSON for:

  • API requests and responses: Industry standard, no debate
  • Configuration generated by programs: Easier to write correctly from code
  • Data that needs strict validation: JSON Schema is powerful and widely supported
  • Small configuration files: Verbosity isn't a problem when files are tiny
  • Data interchange between systems: Maximum compatibility
  • Browser-based config: Native parsing without libraries

Example JSON configuration:

{
  "database": {
    "host": "localhost",
    "port": 5432,
    "name": "myapp",
    "pool": {
      "min": 5,
      "max": 20
    }
  },
  "features": {
    "authentication": true,
    "analytics": false,
    "darkMode": true
  },
  "cache": {
    "enabled": true,
    "ttl": 3600
  }
}

Clear, unambiguous, machine-readable. No surprises.

JSON structure diagram

YAML: Human-Friendly Configuration

YAML (YAML Ain't Markup Language) was explicitly designed for human readability and writability. No brackets, minimal commas, no quotes (usually). Just clean hierarchical structure through indentation.

YAML's Strengths

  • Readable: Cleaner, less cluttered than JSON
  • Comments: Native comment support (JSON doesn't have this)
  • Multi-line strings: Handles long text elegantly
  • Less verbose: No closing brackets or repeated quotes
  • Anchors and aliases: DRY (Don't Repeat Yourself) features built-in
  • Established in DevOps: Docker Compose, Kubernetes, CI/CD all use YAML

When YAML Wins

Use YAML for:

  • Configuration files humans edit frequently: Docker Compose, Kubernetes, CI/CD
  • Large configuration files: Conciseness makes big configs manageable
  • Configuration needing comments: Document why settings exist
  • Multi-line strings: Welcome messages, SQL queries, templates
  • Team prefers it: Developer happiness matters
  • Infrastructure as code: The ecosystem expects YAML

Same configuration in YAML:

database:
  host: localhost
  port: 5432
  name: myapp
  pool:
    min: 5
    max: 20

features:
  authentication: true
  analytics: false
  darkMode: true

cache:
  enabled: true
  ttl: 3600

Cleaner, easier to scan, less visual noise.

YAML with Comments and Multi-line

# Database configuration
database:
  host: localhost
  port: 5432
  # Connection pool settings
  pool:
    min: 5  # Minimum connections
    max: 20  # Maximum connections

# Feature flags
features:
  authentication: true
  analytics: false  # Disabled until GDPR compliance

# Welcome message shown to new users
welcome_message: |
  Welcome to our application!
  
  This is a multi-line message
  that spans several lines
  and preserves formatting.

# SQL query for user lookup
user_query: >
  SELECT id, name, email
  FROM users
  WHERE active = true
  ORDER BY created_at DESC

Try doing that cleanly in JSON. You can't.

YAML configuration example

The Gotchas: Where Each Format Hurts

JSON's Pain Points

  • No comments: Can't explain why a setting exists. Workarounds feel hacky
  • Strict syntax: Forget a comma? Invalid. Trailing comma? Invalid. No mercy
  • Verbose: Lots of brackets, quotes, commas. Visual noise in large files
  • Multi-line strings: Require escaping newlines. Ugly and hard to read
  • No trailing commas: In many languages they're allowed, but not in JSON
  • Must quote all keys: Even when unnecessary in JavaScript

Example of JSON pain:

{
  "description": "This is a long description that spans multiple lines and needs to be readable but JSON makes it ugly with escaped newlines",
  "_comment": "This is a hack for comments",
  "items": [
    "item1",
    "item2",
    "item3"  // NO TRAILING COMMA ALLOWED
  ]
}

YAML's Pain Points

  • Indentation sensitive: Mix tabs and spaces? Breaks. Wrong indentation? Breaks silently
  • Type coercion surprises: `no` becomes boolean false. `012` might be octal. Norway's code `NO` becomes false
  • Multiple ways to express same thing: `true`, `True`, `TRUE`, `yes`, `Yes`, `on` all mean true
  • Version differences: YAML 1.1 and 1.2 have incompatibilities
  • Complex spec: YAML is actually quite complex under the hood
  • Harder to generate: Getting indentation right programmatically is annoying

Example of YAML pain:

countries:
  norway: NO  # Wait, this becomes boolean false!
  scotland: off  # This also becomes boolean false!

versions:
  octal: 012  # This might become 10 in decimal!
  string: "012"  # Quote it to prevent conversion

booleans:
  - yes  # true
  - Yes  # also true
  - true  # also true
  - True  # also true
  # Inconsistency can confuse

These aren't theoretical. I've hit every one of these bugs in production.

Side-by-Side Comparison

Readability

Winner: YAML – Less visual noise, easier to scan, especially for large files

Writability

Winner: YAML – Fewer characters to type, no need to match brackets

Error-Prone

Winner: JSON – Strict syntax catches errors immediately. YAML can fail silently

Tool Support

Winner: JSON – Better editor support, validation, and formatting tools

Comments

Winner: YAML – Native comments. JSON has none

Machine Generation

Winner: JSON – Easier to generate correctly from code

Portability

Winner: JSON – Works everywhere, truly universal

For Humans

Winner: YAML – More pleasant to read and edit

My Recommendations

After using both extensively, here's when I use each:

Use JSON When

  • Building APIs: Request/response bodies should be JSON
  • Data interchange: Between systems, languages, platforms
  • Browser applications: Native parsing without libraries
  • Small configs: Few lines where verbosity doesn't hurt
  • Machine-generated: Programs writing config files
  • Strict validation needed: JSON Schema is powerful
  • Team is uncomfortable with YAML: Don't force tools people don't want

Use YAML When

  • CI/CD pipelines: GitHub Actions, GitLab CI, CircleCI expect YAML
  • Infrastructure as code: Docker Compose, Kubernetes, Ansible use YAML
  • Application config: Database settings, feature flags, app config
  • Large config files: Conciseness and comments improve maintainability
  • Need comments: Explaining why settings exist is valuable
  • Multi-line content: Welcome messages, templates, embedded scripts
  • Team prefers it: Developer happiness affects productivity

The Hybrid Approach

Many projects use both. Each format for its strengths. This is totally valid:

my-project/
├── config/
│   ├── database.yml        # Human-edited config
│   ├── features.yml         # Feature flags with comments
│   └── environments.yml     # Environment-specific settings
├── api/
│   ├── requests.json        # API examples
│   └── schema.json          # JSON Schema validation
├── .github/
│   └── workflows/
│       └── deploy.yml       # CI/CD in YAML
└── package.json             # Dependency config (JSON standard)

Use JSON for APIs and data. Use YAML for configuration and infrastructure. Each does what it does best.

Best Practices for Each Format

JSON Best Practices

  • Use a linter: jsonlint catches syntax errors
  • Format consistently: 2 or 4 space indentation, pick one
  • Validate against JSON Schema: When structure matters
  • Consider JSON5: Allows comments and trailing commas (if tools support it)
  • Keep files small: Large JSON files are hard to maintain
  • Use consistent key naming: camelCase or snake_case, not both

YAML Best Practices

  • Use only spaces, never tabs: Configure editor to convert tabs to spaces
  • Configure editor: Show whitespace characters, highlight indentation
  • Use yamllint: Catches common mistakes early
  • Quote ambiguous strings: "no", "off", "012", "yes" should be quoted
  • Be consistent with booleans: Pick true/false and stick with it
  • Add comments liberally: That's the whole point of YAML
  • Use anchors for DRY: Avoid repeating the same config blocks

YAML anchors example:

defaults: &defaults
  timeout: 30
  retries: 3
  logLevel: info

development:
  <<: *defaults
  logLevel: debug  # Override just this one

production:
  <<: *defaults
  timeout: 60  # Override just this one

Tooling Support

JSON Tools

  • jq: Command-line JSON processor
  • JSON Schema: Validation and documentation
  • Prettier: Formatting
  • ESLint: Linting JSON in JavaScript projects
  • Every editor: Built-in JSON support

YAML Tools

  • yamllint: YAML linter
  • yq: YAML processor (like jq for YAML)
  • Prettier: Also formats YAML
  • VS Code YAML extension: Excellent editing support
  • Red Hat YAML extension: Kubernetes schema validation

Migration Between Formats

Sometimes you need to convert. Both directions work:

# JSON to YAML
cat config.json | yq -y > config.yml

# YAML to JSON
cat config.yml | yq -c > config.json

Most languages have libraries for both formats, so converting in code is straightforward.

The Real Answer

The "JSON vs YAML" debate misses the point. They solve different problems:

  • JSON excels at: Data interchange, strict validation, machine parsing, universal compatibility
  • YAML excels at: Human editing, configuration files, documentation through comments, readability

Don't pick one and use it everywhere. That's dogma, not pragmatism. Use JSON where precision and universality matter. Use YAML where readability and comments matter.

Let your use case drive the decision:

  • API contract: JSON
  • Database config file: YAML
  • Package manager: JSON (convention)
  • CI/CD pipeline: YAML (convention)
  • Application config: YAML (comments help)
  • Data export: JSON (compatibility)

And if someone tells you one is objectively better than the other in all situations? They haven't used both enough to understand their respective trade-offs. Both have their place. Use the right tool for the job.