ZairussalamTools

JSON vs YAML for Config Files: Pick the Right Tool, Skip the Pain

A practical guide to choosing between JSON and YAML for configuration files, with concrete gotchas and recommendations for Kubernetes, APIs, and more.

·Ibrahimsyah Zairussalam·

Every project hits the same fork in the road: JSON or YAML? Both are everywhere, both look simple, and both have foot-guns that will ruin a Friday deploy if you pick wrong. Here's how I decide.

The Short Version

JSON is a data interchange format that happened to get used for config. YAML is a config format that happens to be a superset of JSON. That's the whole story — and it explains every tradeoff that follows.

Quick heuristic

If a machine is the primary author, use JSON. If a human is the primary author, use YAML. If both, pick based on which mistakes you can afford.

Where JSON Wins

JSON's strictness is its superpower. There's exactly one way to write an object, one way to write a string, and the parser will slap you for trailing commas. That's great when you're generating payloads programmatically or shipping API responses where deterministic output matters.

  • API request and response bodies — every HTTP client and server speaks it natively.
  • Package manifests (package.json, composer.json) — small, structured, machine-edited most of the time.
  • Serialization between services — no ambiguity, no locale surprises.
  • Anything stored in a database as a blobjsonb columns in Postgres exist for a reason.

The lack of comments hurts, yes. But if your config file is so complex that it needs paragraphs of explanation, your config file is the problem.

Where YAML Wins

YAML is written for humans who edit by hand. The indent-based syntax, anchors for reuse, and multi-line strings are genuinely useful when a single file might be 400 lines and touched by six different people.

  • Kubernetes manifests — the ecosystem assumes YAML, period.
  • CI pipelines (GitHub Actions, GitLab CI, CircleCI) — readable, diff-friendly.
  • Ansible playbooks — imperative-ish flows read better with YAML's flow.
  • Docker Compose — multi-service config with shared fragments via anchors.

The tradeoff: YAML has opinions about your keys. Strong ones.

The Gotchas That Will Bite You

YAML's "human friendly" design means it tries to guess what you meant. Sometimes it guesses wrong.

The Norway Problem

countries:
  - NO   # parsed as false
  - SE
  - DK

The classic. NO, YES, ON, OFF, TRUE, FALSE — all coerced to booleans in YAML 1.1. Country codes, feature flags, enum strings — any of them can silently flip. Always quote strings when the content could look like anything else.

Indent Sensitivity

Tabs are forbidden. Mixing two-space and four-space indentation inside one file will either error or silently re-parent a block. JSON doesn't care about whitespace; YAML cares a lot.

Anchors and Aliases

YAML lets you define a chunk once and reuse it:

Anchors save repetition, but hide behavior

Powerful. Also opaque — someone reading this for the first time has to mentally expand the anchor to know what the actual config is. Use sparingly.

JSON's No-Comment Problem

You want to leave a note for the next developer? You can't. The closest workaround is a dummy key:

It's ugly. It also survives programmatic round-trips, unlike YAML comments in many parsers.

Trailing Commas

JSON doesn't allow them. JSON5 and JSONC do. If your editor auto-formats with trailing commas and you paste into a strict JSON parser, things break at runtime, not at save time.

Side-by-Side

JSON
  • Strict, predictable, no ambiguity
  • Universal parser support
  • No comments (workarounds are ugly)
  • Verbose for deeply nested config
  • Great for machines, okay for humans
  • Trailing commas invalid
YAML
  • Readable, supports comments
  • Anchors and references for DRY config
  • Indent-sensitive, whitespace matters
  • Implicit type coercion (the Norway problem)
  • Slower parsers, bigger dependency footprint
  • Great for humans, okay for machines

Recommendations by Use Case

Use CasePickWhy
Kubernetes manifestsYAMLEcosystem, readability, anchors
API request/responseJSONInterop, strict schema
CI pipeline definitionsYAMLHand-edited, benefits from comments
package.json style manifestsJSONTool-managed, deterministic diffs
App runtime config (12-factor)JSON or env varsParsing simplicity
Docker ComposeYAMLStandard, plus anchors
Secrets at restNeither (use a vault)Both will leak if committed
LLM structured outputJSONModels are trained on it, stricter grammar

Converting Between Them

Round-tripping is fine for pure data, but you lose YAML comments and anchors when you convert to JSON. Going from JSON to YAML is safer — you just get a less compact version of the same tree.

When I need to check a YAML file for a sneaky type coercion, I convert it to JSON and inspect the actual parsed values. A "NO" that becomes false is immediately obvious once quotes are gone.

And for the reverse — I pretty-print and validate JSON before committing it. Syntax errors in a 400-line config are easier to spot when braces line up.

The Meta Rule

Pick the format that matches who edits the file most. If it's humans, YAML — and quote your strings. If it's code, JSON — and don't fight it with comments. The worst outcome is a team that can't agree, so half the project is JSON and half is YAML with no rule for which goes where.

Pick once, document the choice, move on.