YAML vs JSON: Syntax Comparison & Conversion Tips

YAML and JSON are two of the most popular data serialization formats in software development. JSON dominates API communication, while YAML is the go-to for configuration files. Understanding how they compare — and how to convert between them — is a practical skill every developer needs. This guide breaks down the differences with side-by-side examples.

Quick Comparison

  • JSON: Strict syntax, machine-friendly, no comments, great for APIs
  • YAML: Flexible syntax, human-friendly, supports comments, great for config files

Syntax Side by Side

Here's the same data represented in both formats:

JSON

{
  "server": {
    "host": "localhost",
    "port": 8080,
    "debug": true,
    "allowed_origins": [
      "https://example.com",
      "https://app.example.com"
    ],
    "database": {
      "driver": "postgres",
      "connection": "postgresql://localhost:5432/mydb"
    }
  }
}

YAML

# Server configuration
server:
  host: localhost
  port: 8080
  debug: true
  allowed_origins:
    - https://example.com
    - https://app.example.com
  database:
    driver: postgres
    connection: postgresql://localhost:5432/mydb
💡 Notice the difference: The YAML version is more compact, uses indentation instead of braces, and supports comments. The JSON version is more explicit with its structure.

Key Differences

1. Comments

YAML supports comments with #. JSON does not support comments at all (though JSONC and JSON5 do).

# YAML allows comments
server:
  host: localhost  # This is the server host
  port: 8080       # Default port

2. Quotes

JSON requires double quotes for all strings and keys. YAML usually doesn't need quotes — they're only required when a string could be misinterpreted:

# YAML: no quotes needed for most strings
name: Alice
version: "3.0"    # Quoted to prevent parsing as float

# JSON: quotes always required
{"name": "Alice", "version": "3.0"}

3. Data Types

Both support strings, numbers, booleans, null, arrays, and objects. But YAML has some quirks:

# YAML auto-detects types (sometimes surprisingly)
count: 42          # integer
price: 19.99       # float
active: true       # boolean
empty: null        # null
version: "1.0"     # string (quoted to avoid float)
zip: "01onal"      # string
date: 2024-03-12   # parsed as date in some YAML parsers!
⚠️ YAML gotcha: Values like yes, no, on, off are treated as booleans in YAML 1.1. The string NO becomes false! YAML 1.2 fixed this, but not all parsers use 1.2 by default.
# YAML 1.1 surprise
country: NO     # Parsed as boolean false, not "NO" (Norway)!
answer: yes     # Parsed as boolean true

# Fix: use quotes
country: "NO"
answer: "yes"

4. Multi-line Strings

YAML excels at multi-line strings with its block scalar indicators:

# Literal block (preserves newlines)
description: |
  This is line one.
  This is line two.
  This is line three.

# Folded block (joins lines with spaces)
summary: >
  This is a long sentence
  that will be folded into
  a single line.

# JSON equivalent (escaped newlines)
{"description": "This is line one.\nThis is line two.\nThis is line three.\n"}

5. Anchors and Aliases

YAML supports reusing values with anchors (&) and aliases (*), which JSON cannot do:

# Define an anchor
defaults: &defaults
  adapter: postgres
  host: localhost
  port: 5432

# Reuse with alias
development:
  database:
    <<: *defaults
    database: myapp_dev

production:
  database:
    <<: *defaults
    database: myapp_prod
    host: db.example.com

Converting Between Formats

Python

import json
import yaml

# YAML → JSON
with open("config.yaml") as f:
    data = yaml.safe_load(f)

with open("config.json", "w") as f:
    json.dump(data, f, indent=2)

# JSON → YAML
with open("config.json") as f:
    data = json.load(f)

with open("config.yaml", "w") as f:
    yaml.dump(data, f, default_flow_style=False)

Command Line

# YAML → JSON (requires yq)
yq -o=json config.yaml

# JSON → YAML (requires yq)
yq -P config.json

# Python one-liner: YAML → JSON
python3 -c "import sys,yaml,json; print(json.dumps(yaml.safe_load(open(sys.argv[1])),indent=2))" config.yaml
⚠️ Always use yaml.safe_load() in Python, never yaml.load() without a Loader. The unsafe loader can execute arbitrary Python code — a serious security vulnerability.

When to Use Which?

  • Use JSON for: APIs, data interchange, browser JavaScript, storage formats, anything machines read/write
  • Use YAML for: Configuration files (Docker Compose, Kubernetes, CI/CD pipelines, Ansible), anything humans frequently edit
💡 Fun fact: YAML is actually a superset of JSON. Every valid JSON document is also valid YAML. This means you can use JSON syntax inside a YAML file when it's convenient.

Common YAML Pitfalls

  1. Indentation errors: YAML uses spaces only (not tabs). Inconsistent indentation causes parsing failures
  2. Boolean surprise: Unquoted yes, no, on, off become booleans
  3. Number coercion: 3.0 becomes a float, 010 can be octal
  4. Colon in strings: title: Hello: World fails — must be quoted: title: "Hello: World"
  5. Security: Unsafe YAML loaders can execute arbitrary code via tags like !!python/object

🛠️ Convert YAML & JSON Online

Open YAML Tool →

Further Reading