iLoveConverter
Categories 11 categories
DataJSONYAMLTOML

JSON vs YAML vs TOML: Configuration Formats Compared Honestly

iLoveConverter Team 5 min read

On this page

Every developer accumulates opinions about configuration formats, usually earned through a YAML indentation scar. The three dominant formats coexist for real reasons, and moving between them is a daily task — CI pipelines want YAML, app configs want TOML, APIs want JSON. Here’s the honest comparison and the conversion traps worth knowing before you press convert.

The one-line version

  • JSON (2001) — the universal data interchange. Machine-first, verbose, zero comments.
  • YAML (2001) — the human-readable heavyweight. Indentation-driven, feature-rich, occasionally treacherous.
  • TOML (2013) — the config-files-with-dignity format. Explicit and unambiguous, made for files a person maintains by hand.

JSON: the interchange backbone

JSON won because it’s boring: a spec one page long, parser in every language, and structure that maps directly to programming data types. That’s why it’s the language of APIs, package registries and browser tooling — anywhere a machine talks to another machine.

Its limits are human ones. No comments (the eternal complaint — every workaround, from "//" keys to dead config entries, is a scar), mandatory quoting and braces, and multi-line strings that get ugly fast. JSON is optimized for writing by programs, and you notice immediately when you’re forced to hand-edit a 200-line package-lock.json.

One subtlety worth respecting: JSON’s number model. Large integers beyond 2^53 lose precision in JavaScript tooling (IDs from other systems silently corrupt), and duplicate keys are technically undefined behavior — most parsers keep the last, which can hide data on conversion.

YAML: powerful and occasionally dangerous

YAML’s pitch is readability: nested structure through indentation, lists as dashes, minimal punctuation. It’s the native tongue of Kubernetes, GitHub Actions, and every CI system — which is why “converting YAML to JSON” usually means “making a CI file machine-readable”.

But YAML is a superset with a long feature tail, and the tail bites:

  1. The Norway problem. country: NO parses as boolean false. version: 1.20 parses as the number 1.2, silently mangling software versions. Unquoted scalars get type-inferred in ways that surprise everyone eventually.
  2. Anchors and aliases (&anchor, *alias) let one block reference another — brilliant for deduplicating big pipelines, and a converter that doesn’t expand them produces JSON that’s structurally wrong.
  3. Multi-document files (--- separating documents) and multi-line strings (the | / > family) carry semantics that naive converters flatten.
  4. Indentation IS the structure — copy-paste a block from chat and you can silently break or merge nesting in ways that still parse as valid YAML. This is the “scar” every YAML user has.

Handled by a proper parser, YAML is excellent for its niche: large human-maintained orchestration files. Handled by regex, it’s how incidents happen.

TOML: the config file that behaves

TOML took the opposite bet: make every structure explicit. Tables are [sections], key-values are obvious, dates get a native type, and there’s exactly one way to write any given thing — no type inference surprises, no whitespace-as-structure. Rust’s ecosystem, Python’s pyproject.toml and Cargo standardized on it for good reason: a TOML file read by three different parsers is the same file.

Its cost is verbosity at depth: deeply nested data becomes chains of [a.b.c] headers, and giant repeating structures get repetitive. TOML optimizes for files humans edit carefully, not for arbitrary data payloads — which is exactly what configuration is.

Converting between them — the traps

Conversion between the three is a lossy-boundary negotiation, and knowing which direction is “safe” saves debugging hours:

  • YAML → JSON is the safest direction if the converter expands anchors/aliases and multi-documents properly. The trap: YAML’s unquoted strings like on, off, yes — a converter that type-infers will happily turn your release branch name into true.
  • JSON → YAML is lossless structurally (YAML can represent all of JSON — JSON is technically valid YAML), but you may gain YAML’s type-inference quirks on re-parse: quote anything that looks like a number, version, or boolean word.
  • JSON → TOML hits TOML’s strict typing: JSON’s mixed-type arrays ([1, "a", true]) are invalid in TOML — a converter must either error honestly or stringify values (which corrupts types downstream). Deeply nested JSON also lands as awkward header chains.
  • TOML → JSON is clean — TOML’s explicitness maps directly; the only subtlety is TOML’s native datetime type, which JSON represents as a string (keep it ISO-formatted or lose the semantics).

Our converters (JSON to YAML, YAML to JSON, JSON to TOML, and the format guides for JSON, YAML, TOML) parse with real parsers — never regex — and all of them run locally in the browser, which matters more than usual here: config files routinely contain infrastructure topology, internal hostnames, and secrets. A “paste your Kubernetes YAML” website is a leak vector; converting in your browser is not.

Which should you use?

  • Building an API or anything machine-to-machine → JSON, no contest.
  • CI/CD, Kubernetes, anything in the DevOps ecosystem → YAML — the ecosystem decided for you.
  • Application config a human maintains by hand (Rust, Python, Go projects) → TOML.
  • Converting between them → use real parsers, quote ambiguous scalars, and re-validate types on the other side.

FAQ

Is YAML valid JSON?

No — but the reverse is true: every JSON document is valid YAML (JSON was a YAML subset in early versions and remains parseable by modern YAML parsers). That one-way street is why JSON → YAML “just works” and the reverse needs a real parser.

Why does my version number change when converting YAML?

YAML infers types on unquoted scalars: 1.20 becomes the float 1.2, 1.0 might become 1. Quote version strings (version: "1.20") at the source, or use a converter that preserves original scalar text.

Can TOML represent everything JSON can?

No. TOML forbids mixed-type arrays, and JSON’s arbitrary nesting depth is legal but painful as [a.b.c.d] header chains. Converters either reject such structures or coerce types — read what your converter did rather than assuming a clean mapping.

Why do config formats need comments anyway?

Because configuration encodes decisions (“this timeout is 30s because of the upstream’s p99”), and decisions without context get “fixed” by the next person. JSON’s comment-less design is its most-resented feature; YAML and TOML both have first-class comments.

Try it yourself — free, right in your browser

Everything mentioned in this guide runs locally on this site: no upload, no watermark, no sign-up.

Format deep-dives: JSON (.json) , YAML (.yml.yaml) , TOML (.toml)