Monu Tools

YAML vs JSON: Which One Should Your Config Use?

By Maxwell AboagyeLast updated 2026-06-27

The yaml vs json question almost never has a universal answer, because the two formats are tuned for opposite jobs. JSON is built for programs to exchange data; YAML is built for people to hand-edit config. Pick the wrong one and you either fight a wall of quotes and braces or you spend an afternoon chasing a value that silently turned into a boolean. This guide gives you a quick rule, the footguns of each, and when to reach for TOML instead. If you just need to move data across the line, the YAML to JSON converter handles the round trip in your browser.

Try the YAML ⇄ JSON toolConvert YAML to JSON and JSON back to YAML, both ways. Validates as it converts and shows clear errors. Everything runs in your browser.

The 60-second difference

YAML is a strict superset of JSON, which means every valid JSON document is also valid YAML. The reverse is not true. YAML adds indentation-based structure, comments with #, anchors and references for reuse, and a small zoo of scalar types it infers without quotes. JSON adds none of that: braces, brackets, double-quoted keys, commas, and four primitive types (string, number, boolean, null). That smallness is the point. There is almost nothing to get wrong in JSON and almost nothing to argue about.

DimensionYAMLJSON
CommentsYes, with #No, not in the spec
StructureIndentation (whitespace-sensitive)Braces and brackets
Multi-line stringsNative, with | and >Escaped \n inside one line
Type inferenceAggressive (the Norway problem)Explicit, only four primitives
ReuseAnchors and aliases (& and *)None
Parsing riskHigher, ambiguous edge casesLow, one obvious reading
Best fitHuman-edited configAPIs and machine-to-machine

Where YAML wins

YAML earns its place wherever a human reads and edits the file by hand. Kubernetes manifests, CI pipelines, Ansible playbooks, and Docker Compose all chose YAML for the same reasons. Comments let you explain why a setting exists, which is often more valuable than the setting itself. Indentation removes the closing-brace noise, so a deeply nested config stays readable. And multi-line strings are first class: a shell script or a certificate can sit inline without a single escaped newline.

# Block scalars keep newlines and indentation intact
startup:
  command: |
    set -euo pipefail
    echo "booting"
    ./run --config prod.yaml
  retries: 3  # inline comments survive in YAML, never in JSON

Write that same script as a JSON string and every newline becomes \n on a single long line. For anything a person maintains, that difference compounds fast.

The footguns: the Norway problem and indentation

YAML's convenience is also its hazard. The most famous case is the Norway problem: an unquoted no is parsed as the boolean false, so a list of country codes that includes NO (Norway) can lose that entry or turn it into a boolean. The same trap catches yes, on, and off, all of which older YAML parsers coerce to booleans. A version string like 1.20 may be read as the number 1.2, and a value like 0x10 may become an integer. The fix is blunt: quote anything that should stay a string.

The second footgun is whitespace. Because structure is indentation, a single stray tab or an off-by-two space changes the meaning of the document, and the error often surfaces far from the typo. Mixing tabs and spaces is rejected outright by most parsers. JSON has neither problem: its braces make nesting unambiguous, and a formatter can always reindent it without changing meaning.

Where JSON wins

For anything two programs exchange, JSON is the default and should usually stay that way. Every language ships a parser, every HTTP client speaks it, and there is exactly one way to read a given document. There is no type inference to second-guess, no indentation to corrupt in transit, and no anchors to expand. JSON is also faster to parse and far harder to make ambiguous, which matters when the producer and consumer are written by different teams in different languages.

  • REST and GraphQL payloads, where ubiquity and speed beat readability.
  • Log lines and event streams, where one record per line parses cleanly.
  • Anything cached, signed, or hashed, where a single canonical form is required.
  • package.json, tsconfig, and other files tools generate and rewrite.

TOML: a third option for app config

TOML sits between the two and is worth knowing. It reads like an INI file, supports comments, and has no significant whitespace, so the Norway problem and the indentation traps both disappear. Its types are explicit and its dates are first class. The trade-off is that TOML gets awkward once nesting goes more than a level or two deep, where YAML stays flatter. That is why you see TOML in Rust's Cargo.toml, Python's pyproject.toml, and many CLI configs, but rarely in Kubernetes-style documents with deep trees. If your config is mostly flat key-value settings, TOML is often the calmest choice of the three.

Converting between them, and what does not survive

Converting YAML to JSON is lossless for the data itself: every scalar, list, and map maps cleanly onto JSON's four primitives plus arrays and objects. Going the other way, JSON to YAML, is also clean because JSON is a YAML subset. What does not survive the trip is everything YAML adds on top of the data model.

  • Comments. JSON has no place to put them, so # lines are dropped on the way in and never reappear on the way out.
  • Anchors and aliases. They are expanded into duplicated values during conversion, so the reuse is gone even though the data is correct.
  • Key order and formatting. Block scalars, flow style, and your chosen indentation are normalized away.
  • Scalar intent. A quoted "NO" survives, but if it was already coerced to a boolean, the conversion cannot recover the original string.

In practice this means conversion is a one-way door for documentation and reuse. Treat one format as the source of truth and generate the other, rather than editing both. The YAML to JSON converter runs entirely in the browser, so a config full of secrets never leaves your machine, and it shows the parsed result so you can confirm that NO is still a string before you ship it.

When an edge case bites and you want the authoritative rule, go to the source. The behavior of every scalar, tag, and anchor is defined in the YAML 1.2 specification at yaml.org, which spells out exactly which strings the core schema treats as booleans, null, integers, or plain text. If a parser disagrees with you about Norway, that page is where you settle it.

The short version: reach for YAML or TOML when people maintain the file and comments matter, reach for JSON when programs trade the data and one canonical reading matters, and quote your ambiguous scalars no matter which you choose.

Convert YAML and JSON nowConvert YAML to JSON and JSON back to YAML, both ways. Validates as it converts and shows clear errors. Everything runs in your browser.

Related articles