← Back to Blog

YAML vs JSON vs TOML: Choosing the Right Config Format

March 9, 2026 8 min read By CodeTidy Team

Every project needs configuration, and the three dominant formats — YAML, JSON, and TOML — each have strong opinions behind them. This guide compares all three so you can pick the right one for your project, or at least understand why your toolchain chose it for you.

The Same Config in Three Formats

Let's start with a practical example — the same configuration expressed in each format:

JSON

{
  "server": {
    "host": "0.0.0.0",
    "port": 8080,
    "debug": false
  },
  "database": {
    "url": "postgres://localhost:5432/myapp",
    "pool_size": 10,
    "ssl": true
  },
  "allowed_origins": [
    "https://example.com",
    "https://staging.example.com"
  ]
}

YAML

server:
  host: "0.0.0.0"
  port: 8080
  debug: false

database:
  url: "postgres://localhost:5432/myapp"
  pool_size: 10
  ssl: true

allowed_origins:
  - https://example.com
  - https://staging.example.com

TOML

[server]
host = "0.0.0.0"
port = 8080
debug = false

[database]
url = "postgres://localhost:5432/myapp"
pool_size = 10
ssl = true

allowed_origins = [
  "https://example.com",
  "https://staging.example.com",
]

Feature Comparison

FeatureJSONYAMLTOML
CommentsNoYes (#)Yes (#)
Trailing commasNoN/AYes
Multi-line stringsNo (use \n)Yes (| and >)Yes (""")
Date/time typeNo (string only)Yes (implicit)Yes (RFC 3339)
Indentation-sensitiveNoYesNo
Spec complexitySimple (~6 pages)Complex (~80 pages)Moderate (~20 pages)
Nesting depthUnlimitedUnlimitedAwkward beyond 2-3 levels

JSON: The Universal Exchange Format

Strengths

  • Universal support — every programming language has built-in JSON parsing. It's the lingua franca of web APIs.
  • Unambiguous — the spec is tiny and there's only one way to represent data. No surprises.
  • Great tooling — validators, formatters, and converters everywhere. Use our JSON Formatter to instantly beautify JSON config files.
  • Machine-readable — ideal for data exchange between services.

Weaknesses

  • No comments — the single biggest complaint. You can't explain why a setting exists.
  • Verbose — all those quotes and braces add visual noise for humans.
  • No trailing commas — adding an item to the end of a list requires modifying the previous line too, creating noisy diffs.
  • No multi-line strings — embedding SQL queries or templates is painful.

Best for

API responses, data exchange, package.json, tsconfig.json, any config that's primarily machine-generated or consumed. Also see our guide on common JSON errors if you're editing JSON config by hand.

YAML: The Human-Friendly (But Treacherous) Format

Strengths

  • Clean syntax — minimal punctuation makes it pleasant to read and write.
  • Comments — explain why settings exist with # inline comments.
  • Multi-line strings — the | (literal) and > (folded) operators handle long text gracefully.
  • Anchors and aliases — reduce repetition with &anchor and *alias references.

Weaknesses

  • Indentation is semantic — a single misplaced space can change the meaning of your config. Tabs are forbidden.
  • Implicit type coercionyes, no, on, off are parsed as booleans. 3.10 becomes 3.1. The string NO becomes false. This has caused real production incidents.
  • Complex spec — YAML 1.2 is ~80 pages. There are features most developers never learn (document markers, complex keys, flow mappings).
  • Security risks — YAML deserializers can execute arbitrary code in some languages. Always use safe loading functions.

The Norway Problem

The most infamous YAML gotcha: country codes like NO (Norway) are parsed as boolean false. Versions of Node.js have been listed as 3.10 and parsed as 3.1 in CI configs. Always quote strings that could be misinterpreted.

# DANGEROUS — "NO" becomes false
country: NO

# SAFE — quotes force string type
country: "NO"

Best for

Kubernetes manifests, Docker Compose, CI/CD configs (GitHub Actions, GitLab CI), Ansible playbooks — anywhere the ecosystem has already chosen YAML for you. Convert between formats easily with our JSON-YAML Converter.

TOML: The Configuration-First Format

TOML (Tom's Obvious, Minimal Language) was created specifically for configuration files, learning from JSON's and YAML's weaknesses. For a deeper dive, see our guide on what TOML is and why it's replacing YAML.

Strengths

  • Designed for config — not data exchange or document markup. Every feature serves configuration needs.
  • No indentation sensitivity — sections use explicit [headers], so whitespace is purely cosmetic.
  • No type coercion surprises — strings must be quoted, booleans are only true/false. No "Norway problem."
  • Native date/time supportcreated = 2026-03-09T10:30:00Z is a first-class type.
  • Trailing commas allowed — cleaner diffs when adding items to arrays.

Weaknesses

  • Deep nesting is awkward — TOML uses dotted keys ([server.database.primary]) that become unwieldy beyond 2-3 levels.
  • Smaller ecosystem — fewer tools and less IDE support compared to JSON and YAML.
  • Less familiar — developers need to learn a new syntax.

Best for

Application configuration files: Cargo.toml (Rust), pyproject.toml (Python), hugo.toml (Hugo), netlify.toml. Format and convert TOML with our TOML Formatter.

Decision Flowchart

  • Is it an API response or data exchange? → Use JSON.
  • Does the tool/framework require a specific format? → Use what it requires (Kubernetes = YAML, Cargo = TOML, npm = JSON).
  • Is it a flat or shallow config file you control? → Use TOML.
  • Is it a deeply nested config with comments needed? → Use YAML (carefully).
  • Do you need maximum language/tool compatibility? → Use JSON.

Migration Tips

If you're converting between formats:

  • JSON → YAML: Watch for strings that YAML will misinterpret as other types. Quote anything that looks like a boolean or number.
  • YAML → JSON: Comments will be lost. Consider adding a "_comment" key pattern if documentation is critical.
  • JSON → TOML: Flatten deeply nested structures. TOML works best with 1-2 levels of nesting.
  • YAML → TOML: Replace indentation-based nesting with [section] headers. Convert anchors/aliases to explicit values.

For JSON-specific comparisons, see our detailed breakdown of JSON vs XML covering when each format wins.

Quick Reference

Use CaseRecommended Format
REST API responsesJSON
Kubernetes / Docker ComposeYAML
Rust project configTOML
Python project configTOML (pyproject.toml)
CI/CD pipelinesYAML
npm / Node.js configJSON
Hugo / static site configTOML
Data serializationJSON

Working with config files across formats? Use our JSON-YAML Converter to switch between formats instantly, or validate your JSON configs with our JSON Validator to catch syntax errors before deployment.

Drop file to load