JSON and YAML solve the same problem — representing structured data as text — with very different philosophies. JSON optimizes for machines; YAML optimizes for humans. After working with both formats across hundreds of projects, here's our honest take on when each one wins.
The same data, two ways
Let's start with the same data expressed in both formats. Here's a typical Kubernetes-style configuration:
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": "my-app",
"labels": {
"app": "frontend",
"tier": "production"
}
},
"spec": {
"selector": { "app": "my-app" },
"ports": [
{ "port": 80, "targetPort": 8080 }
]
}
}
And the same in YAML:
apiVersion: v1
kind: Service
metadata:
name: my-app
labels:
app: frontend
tier: production
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
Both express the same underlying data. The YAML version is about 30% shorter and (most people would say) easier to read. The JSON version is more explicit about structure — every boundary is marked with punctuation.
Syntax differences that matter
JSON uses punctuation for structure. Braces denote objects, brackets denote arrays, quotes denote strings, commas separate items. Every boundary is unambiguous. The downside: more keystrokes when writing by hand, more visual noise when reading.
YAML uses indentation for structure. The level of indentation determines nesting depth. This is more compact but also more error-prone — accidentally adding or removing a space can change the meaning of your document. The infamous "Norway problem" is YAML's: NO (the country code for Norway) gets parsed as the boolean false in YAML 1.1 because no is one of its boolean keywords.
YAML allows comments. JSON doesn't. This is often the single deciding factor. Configuration files benefit enormously from inline explanation. package.json in Node.js is famously frustrating to maintain partly because you can't comment why a specific dependency version was pinned.
YAML has anchors and references. You can define a value once and reference it elsewhere:
defaults: &defaults
timeout: 30
retries: 3
production:
<<: *defaults
host: prod.example.com
staging:
<<: *defaults
host: staging.example.com
JSON has no equivalent — you'd have to repeat the values or use a templating layer on top.
When JSON wins
- Machine-to-machine communication. APIs, webhooks, message queues — anywhere a program is producing or consuming data without humans in the loop. JSON parsing is faster (native in every browser and language), and the strict syntax leaves no room for ambiguity.
- When you need to be sure about types. YAML's implicit type coercion ("yes" becomes true, "1.0" becomes a number, "NO" becomes false) is helpful when writing by hand but a hazard when generating data programmatically. JSON's types are explicit and unambiguous.
- Large data files. JSON parsers are generally faster than YAML parsers and use less memory. For megabyte-scale documents, the difference is measurable.
- JavaScript-heavy environments. Browsers parse JSON natively with
JSON.parse. YAML requires a third-party library like js-yaml. - Strict schemas. JSON Schema tooling is mature and widely adopted. YAML can use JSON Schema (since YAML 1.2 is a superset of JSON), but the ecosystem is JSON-first.
When YAML wins
- Human-edited configuration. Anything a developer or operator types by hand. YAML's reduced punctuation and support for comments makes daily editing pleasant in a way JSON isn't.
- CI/CD pipelines. GitHub Actions, GitLab CI, CircleCI, and Jenkins all use YAML. The format is essentially the industry standard for build configuration.
- Kubernetes and container orchestration. While Kubernetes accepts both, all official documentation, examples, and community resources use YAML.
- Documentation that includes config. Config snippets embedded in documentation are easier to read in YAML.
- OpenAPI specs. Both formats are valid for OpenAPI, but YAML is more readable for the long, nested structures typical of API specifications.
The hybrid pattern
A common arrangement in modern systems: humans edit YAML configs, but the build pipeline converts them to JSON before runtime. This gives you the readability of YAML during authoring and the parsing speed of JSON during execution. Our JSON ↔ YAML converter handles this conversion in either direction.
This pattern works particularly well for:
- Application config that's complex enough to benefit from comments
- Infrastructure-as-code where reviewers need to grok diffs
- API specifications where the spec doc is YAML but the served version is JSON
YAML gotchas to know about
The Norway problem. In YAML 1.1 (still the default for many libraries), the unquoted string NO becomes the boolean false. Same for YES, ON, OFF. To preserve a literal string that looks like a boolean, quote it: country: "NO".
Tabs are illegal for indentation. YAML insists on spaces. Most editors handle this automatically, but if you switch between editors, mismatched tabs and spaces can break parsing in subtle ways.
Indentation must be consistent. Within a single block, all items at the same level must be indented identically. Most YAML errors come from accidentally mismatching indentation.
Implicit typing surprises. Versions like 1.10 parse as the float 1.1 in YAML 1.1 (trailing zeros lost). To preserve, use version: "1.10". Sexagesimal numbers (1:23:45) might parse as base-60 numerics. Always quote ambiguous values.
JSON gotchas to know about
No trailing commas. Valid in JavaScript, invalid in JSON. {"a": 1,} fails to parse. This is the #1 cause of "invalid JSON" errors.
Double quotes only. Single quotes around strings or keys cause parse failures.
No comments. Period. If you need comments, use JSONC (for VS Code) or JSON5, or switch to YAML.
Number precision. JSON numbers are IEEE 754 doubles — integers above 2^53 lose precision. For 64-bit IDs, encode as strings.
The verdict
Use JSON for: APIs, programmatic data interchange, large data files, anywhere humans aren't editing the file directly. Use YAML for: configuration files that humans edit, CI/CD pipelines, Kubernetes manifests, anywhere the readability matters more than parsing speed.
When in doubt, ask: who edits this file? If the answer is "a program," choose JSON. If the answer is "a person," choose YAML.
And remember — you can have both. Authoring in YAML, runtime in JSON, with a build step doing the conversion, is a perfectly normal pattern.