๐ŸชบToolNest
developer7 min read

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.

TN

ToolNest Team

August 1, 2025

#YAML#JSON#configuration#developer tools

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