YAML and JSON express the same data — usually
Both formats describe nested key-value structures and lists. YAML adds: human-readable indentation instead of braces, comments, optional explicit types, anchors and aliases for repeated values, and multiple flow styles. JSON is stricter: no comments, no trailing commas, double quotes only on strings, no aliases. Any JSON document is valid YAML 1.2 — YAML is a superset.
Bidirectional conversion is mostly lossless, with caveats: YAML comments are stripped when going to JSON (JSON has no comments). YAML anchors and aliases get expanded into duplicate inline values. Multi-document YAML (separated by ---) collapses to the first document only. Going JSON → YAML always succeeds.
The "Norway problem" and other YAML footguns
YAML's optional explicit types make it weirdly fragile. A famous example:
countries: - GB - US - NO # YAML 1.1 parses this as boolean false
"NO" is interpreted as boolean false in YAML 1.1; same for "yes", "no", "on", "off", "y", "n". YAML 1.2 fixed this, but many parsers (including PyYAML's default) still default to 1.1 behavior. The fix: always quote strings that could be ambiguous.
Other surprises: 1.0 is a float (parses as 1.0, not the string "1.0"). Leading zeros (007) get parsed as octal in YAML 1.1. 0xFF is hex. Anything that looks like a date (2026-01-15) becomes a Date object. When in doubt, quote it.
When to use which format
- Use YAML for configuration files humans edit by hand. Comments are essential for explaining why a setting exists; multi-line strings are clean; indentation matches the structure visually. Standard for Kubernetes, GitHub Actions, Docker Compose, Ansible, OpenAPI specs.
- Use JSON for machine-to-machine communication, APIs, lockfiles. Stricter parsing rules mean fewer surprises. Faster to parse. Universal language support without a dependency.
- Never use either for binary data (use Base64 inside JSON), or for data that needs to be queried efficiently (use a proper database). Both are read-once-into-memory formats.
Anchors and aliases — the YAML feature JSON doesn't have
defaults: &defaults timeout: 30 retries: 3 production: <<: *defaults host: prod.example.com staging: <<: *defaults host: staging.example.com retries: 1 # override one field
&defaults defines an anchor. *defaults references it. <<: merges keys. When this YAML converts to JSON, the anchors get expanded — each section ends up with its own copy of the fields. The output is larger but the meaning is identical.
Anchors are useful for DRY config (don't repeat yourself). They have a cost: complex configs with chained anchors become hard to read. Use sparingly.
Common use cases
- Convert a Kubernetes YAML manifest to JSON for an API call
- Convert a JSON API response to YAML for a config file
- Validate that YAML is parseable before committing
- Sort keys alphabetically for cleaner diffs
Frequently asked questions
My YAML "country: NO" became "country: false". Why?
The "Norway problem" — YAML 1.1 parses unquoted "NO", "YES", "ON", "OFF" as booleans. js-yaml uses YAML 1.2 by default which fixes this, but many parsers (PyYAML default) still have the issue. Always quote strings that could be ambiguous: <code>country: "NO"</code>.
Comments disappeared after YAML → JSON.
Expected. JSON has no comment syntax. The conversion preserves data but strips all comments. If you need comments in your output, use YAML (or JSONC / JSON5).
Anchors and aliases got expanded into duplicates.
JSON has no anchor concept, so <code>&defaults / *defaults</code> gets resolved at conversion time into inline copies. The data is identical; the JSON is just bigger. If you need referential structure, use a different format.
Multi-document YAML (--- separators) only produces one document.
Correct. Standard YAML supports multiple documents in one file; standard JSON does not. This tool loads only the first document. To convert all documents, split the YAML on <code>---</code> first and convert each independently.
Why is my JSON output bigger than I expected?
YAML is more compact than indented JSON for the same data — indentation only, no quotes on keys, no commas. Pick "minified" JSON indent or accept the size difference.