PlayTools

JSON vs YAML vs TOML: Choosing a Config Format (and Converting Safely)

Developers · Updated October 2, 2026 · 4 min read

JSON, YAML and TOML can all describe the same nested data — objects, lists, strings, numbers and booleans. They differ in who they are written for. JSON is built for machines exchanging data, YAML for humans editing deeply nested configuration, and TOML for humans editing flat-ish configuration with as few surprises as possible.

The same data in three formats

JSON
{"name": "api", "port": 8080, "debug": false, "tags": ["web", "v2"]}

YAML
name: api
port: 8080
debug: false
tags:
  - web
  - v2

TOML
name = "api"
port = 8080
debug = false
tags = ["web", "v2"]

JSON: strict and universal

  • Every language has a fast, well-tested parser, and browsers parse it natively.
  • The grammar is tiny and unambiguous: double-quoted strings, no trailing commas, no comments.
  • The lack of comments is the main drawback for configuration. JSONC (JSON with comments), used by VS Code settings and tsconfig.json, and JSON5 relax the rules, but they are not interchangeable with plain JSON parsers.
  • Best for: APIs, data files, lock files and anything written by programs.

YAML: readable, powerful, occasionally surprising

  • Indentation instead of braces, comments with #, multi-line strings, and anchors (&) and aliases (*) to reuse blocks.
  • Ubiquitous in infrastructure: Kubernetes manifests, GitHub Actions, Docker Compose, Ansible.
  • Implicit typing causes surprises. In YAML 1.1 parsers — still common, including PyYAML — yes, no, on and off are booleans, so the country code NO for Norway becomes false. A version written as 1.10 becomes the number 1.1. Quote anything that must stay a string.
  • Indentation errors change meaning silently: a key indented one level too far belongs to a different object without any parse error.
  • Best for: hand-edited, deeply nested configuration where comments matter.

TOML: obvious by design

  • Key = value pairs grouped into [tables], with explicit types: strings are always quoted, and dates are a native type.
  • No significant indentation and no implicit booleans, so far fewer surprises than YAML.
  • Used by Rust’s Cargo.toml, Python’s pyproject.toml and many command-line tools.
  • Deeply nested data gets verbose — arrays of tables use [[double brackets]] — so it suits configuration more than data.
  • Best for: application and package configuration that people edit by hand.

Converting without losing anything

JSON maps cleanly into YAML and TOML. Going the other way, watch for:

  • Comments disappear: JSON has nowhere to put them.
  • Anchors and aliases are expanded into full copies.
  • Dates: YAML 1.2 parsers such as the one on this site keep 2024-01-01 as a string; others turn it into a date object, which then serialises as a full timestamp.
  • Large integers above 9,007,199,254,740,991 lose precision when parsed by JavaScript-based tools. Keep IDs as strings.
  • Key order: JSON objects are unordered by specification, though most tools preserve the order they were written in.

The JSON-to-YAML and YAML-to-JSON converters here quote ambiguous strings automatically and show exactly what a parser will see, which is a quick way to debug a configuration that “looks right”.

A practical rule

  1. Data exchanged between programs: JSON.
  2. Configuration in an ecosystem that already chose a format (Kubernetes, GitHub Actions, Cargo, Python packaging): use that format.
  3. New hand-edited configuration: TOML if it is mostly flat, YAML if it is deeply nested and needs reuse — with strings quoted.
  4. Whatever you choose, validate it in CI with a schema so typos fail fast instead of in production.

Validating configuration files

  • JSON Schema describes the expected shape of JSON — and of YAML and TOML, since they map to the same data. Editors such as VS Code use schemas to autocomplete and flag errors as you type.
  • yamllint catches indentation problems, duplicate keys and suspicious truthy values like yes and on.
  • Taplo formats and validates TOML, and understands schemas for common files such as Cargo.toml and pyproject.toml.
  • Kubernetes users can validate manifests against the API schema before applying them; CI pipelines can run any of these checks on every change.

Common YAML mistakes and fixes

Mistake                         Fix
country: NO     → false         country: "NO"
version: 1.10   → 1.1           version: "1.10"
time: 12:30     → 750 (YAML 1.1)  time: "12:30"
Tabs for indentation            spaces only
key: value: more                key: "value: more"
Duplicate keys (last wins)      remove the duplicate

Converting a suspicious file to JSON shows instantly how a parser reads it: a value that comes out as a number or boolean when you meant text needs quotes.

Multi-line strings and escaping

JSON strings are single-line: line breaks must be written as \n, quotes as \", and other special characters as \u escapes. YAML offers two block styles for long text. A literal block (|) keeps every line break, which suits scripts and certificates; a folded block (>) joins lines into one paragraph, which suits long descriptions. Adding a minus sign (|- or >-) drops the final line break. TOML uses triple-quoted strings () for multi-line text, with a literal form (''' ''') that does not process escapes — convenient for Windows paths and regular expressions.

Size and performance

For data sent over the network, JSON is the practical choice: parsers are extremely fast, and minifying removes whitespace — though gzip or Brotli compression narrows the gap between pretty and minified JSON considerably. YAML parsers are much slower and more complex, which matters little for a configuration file read once at start-up but makes YAML a poor format for high-volume data. For large datasets processed line by line, such as logs, JSON Lines (one JSON object per line) lets programs stream records without loading the whole file into memory.

Tools used in this guide