ToolSite

JSON vs YAML: Which to Use for Config Files?

Compare JSON and YAML for config files: readability, comments, type safety, and ecosystem support. Choose the right format for your project with our free tools.

By ToolSite5 min readguides

Two Formats, One Job

JSON and YAML both represent structured data as plain text. They solve the same underlying problem: serialize nested key-value pairs, lists, and scalars in a format that humans can read and machines can parse. But they feel different in practice, and those differences matter when you're staring at a 200-line config file at 2 a.m.

JSON

JSON (JavaScript Object Notation) is strict and minimal. Every string is double-quoted. Every object is wrapped in braces. Every list is wrapped in brackets. Trailing commas are not allowed. There are no comments.

{
  "server": {
    "host": "0.0.0.0",
    "port": 8080,
    "tls": true
  },
  "database": {
    "engine": "postgresql",
    "pool_size": 10
  }
}

This rigidity is a feature when you're exchanging data between systems. There is exactly one way to write valid JSON. Parsers are fast and predictable. Every programming language has a JSON library in its standard library or near it.

JSON also benefits from JSON Schema, a spec that lets you define exactly what shape your data should have. You can specify required fields, set minimum and maximum values, and constrain string patterns. Most API gateways and validation libraries support JSON Schema out of the box. This gives JSON an advantage for API contracts: you can validate payloads before they touch your application logic.

YAML

YAML (YAML Ain't Markup Language) prioritizes readability for humans. Indentation defines structure. Quotes are optional. Comments start with #.

server:
  host: 0.0.0.0
  port: 8080
  tls: true

database:
  engine: postgresql
  pool_size: 10

Fewer noise characters. The structure is visible at a glance. This is why Kubernetes manifests, Docker Compose files, CI/CD pipelines (GitHub Actions, GitLab CI), and Ansible playbooks all use YAML.

YAML also supports features that JSON lacks. Multi-line strings with the | and > operators let you include blocks of text without escaping newlines. Anchors (&) and aliases (*) let you define a value once and reuse it, reducing duplication in large files. These features matter when your config spans hundreds of lines.

The Comment Problem

JSON has no comments. Period. You cannot annotate a JSON config file with explanations. The workaround, using an _comment key, is ugly and fragile. Tools may strip it.

YAML has comments, and they're one of the main reasons ops teams prefer it. When your Kubernetes deployment has 300 lines, inline comments explaining why replicas: 3 and not replicas: 5 are the difference between a config file and documentation.

If you must use JSON but need comments, consider JSONC (JSON with Comments), which VS Code supports natively. JSONC allows // and /* */ comments. Just remember that standard JSON parsers will reject JSONC files, so strip comments before feeding them to a parser.

Where YAML Goes Wrong

YAML's indentation-based structure is a double-edged sword. A single misplaced space can silently change the meaning of a file. Two spaces vs four is not just a style preference; it can break your deployment.

YAML also has surprising type coercion. The string yes becomes a boolean true. 1.0 becomes a float. 012 becomes 10 (octal). These traps have caused production incidents. The most famous example: a Norwegian town named NO was interpreted as boolean false in a YAML config. The country code for Norway, NO, is not a boolean. But YAML's type system thinks it is.

Other YAML type gotchas to watch for:

  • on, off, yes, no, true, false all become booleans
  • Numbers with leading zeros become octal: 012 equals 10
  • null, NULL, ~ all become null values
  • 1.0 is a float, but 1 is an integer, and 1.0 may lose precision

Always quote strings in YAML that might be ambiguous. Write "yes" instead of yes when you mean the word, not the boolean. Write "012" when you mean a string, not octal. A linter like yamllint can catch these before they reach production.

When to Mix Formats

Some projects use both. You might keep a JSON Schema for API validation, a YAML config for deployment, and a TOML file for build configuration. The formats are not mutually exclusive. Pick the one that fits each use case.

Tools like Docker Compose accept both YAML and JSON (docker-compose.yml and docker-compose.json). If you generate your compose file from a script, JSON is easier to produce programmatically. If you maintain it by hand, YAML is easier to read.

Quick Comparison

| | JSON | YAML | |---|---|---| | Comments | No | Yes (#) | | Whitespace | Ignored | Significant (indentation) | | Quotes | Required for strings | Optional | | Trailing commas | Not allowed | Not applicable | | Multi-line strings | No (use \n) | Yes (|, >) | | Anchors/aliases | No | Yes (&, *) | | Schema validation | JSON Schema | Limited | | Human error surface | Low | High |

When to Use Each

Use JSON when:

  • You're building an API that talks to browsers or mobile apps
  • You need fast, predictable parsing with schema validation
  • Config is generated by a tool, not hand-written
  • You need a format that every language parses identically
  • You're storing data in a document database like MongoDB or CouchDB

Use YAML when:

  • Humans will write and maintain the config file directly
  • You need comments to explain why values are set a certain way
  • The file is part of a DevOps workflow (Kubernetes, Docker, CI)
  • You're using tools that already expect YAML (Ansible, Homebrew formulas)
  • You need anchors and aliases to avoid repeating the same values

If your config is hand-edited by developers, go YAML. If it's consumed by machines and generated by machines, go JSON. If you need both human editing and machine generation, consider keeping a YAML source and converting to JSON at build time.

Try it yourself: open the JSON Formatter and paste a block of JSON to validate it. Then open the YAML Validator and paste a block of YAML. Convert between the two with the YAML to JSON Converter to see how the same structure looks in each format.

Related Reading