JSON and YAML solve the same fundamental problem — representing structured data as text — but they make opposite tradeoffs. JSON is terse, strict, and unambiguous. Every brace, bracket, and comma is load-bearing. The syntax is so constrained that there's essentially one correct way to represent any given data structure. YAML is loose, expressive, and human-oriented. It uses indentation instead of braces, allows comments, supports multiple syntaxes for the same constructs, and tries to be clever about type inference so you don't have to write quotes around everything.
The tradeoff is real: JSON's strictness means errors are caught at parse time. YAML's flexibility means errors are often silent — valid YAML that represents unintended data structures. Understanding where each format wins and where it creates problems is the key to choosing correctly.
Syntax Comparison
The same data structure in both formats illustrates the differences clearly:
// JSON
{
"name": "api-gateway",
"version": "2.1.0",
"enabled": true,
"replicas": 3,
"ports": [8080, 8443],
"env": {
"LOG_LEVEL": "info",
"TIMEOUT": 30
},
"tags": ["production", "core", "gateway"]
}# YAML
name: api-gateway
version: "2.1.0" # Quoted to preserve as string
enabled: true
replicas: 3
ports:
- 8080
- 8443
env:
LOG_LEVEL: info
TIMEOUT: 30
tags:
- production
- core
- gatewayYAML is visually cleaner — no braces, brackets, or commas. The indentation communicates structure directly. JSON requires more punctuation but is completely unambiguous about types and structure. Notice that YAML requires quotes around "2.1.0" — without them, some YAML parsers would interpret it as a float, producing 2.1. This is a YAML footgun that JSON's mandatory quoting prevents.
YAML Type Inference: Power and Peril
YAML automatically infers types from unquoted values. This can be convenient or catastrophic depending on your data:
| YAML Value | YAML 1.1 Parses As | YAML 1.2 Parses As | JSON Equivalent |
|---|---|---|---|
true | boolean true | boolean true | true |
yes | boolean true | string "yes" | "yes" |
NO | boolean false | string "NO" | "NO" |
3.10 | float 3.1 | float 3.1 | 3.10 (string in JSON) |
0777 | integer 511 (octal) | integer 777 | "0777" |
null | null | null | null |
~ | null | null | N/A |
2026-04-13 | timestamp (date) | string | "2026-04-13" |
The YAML 1.1 vs 1.2 inconsistency is a real-world problem: many tools (Go's gopkg.in/yaml.v2, Python's PyYAML before version 6.0) implement YAML 1.1 even though YAML 1.2 has been the current version since 2009. If yes or no appears in your YAML config — perhaps as country codes, boolean values from a form, or environment settings — you cannot predict how it will be parsed without knowing which version your runtime uses. JSON has no such ambiguity: true is always boolean, "yes" is always a string, and they are never interchangeable.
JSON's Strictness as a Safety Property
JSON's syntax rules are intentionally minimal and unambiguous:
- All string values must be double-quoted — no bare words, no single quotes
- Object keys must be strings (double-quoted) — no bare identifiers, no integer keys
- No trailing commas after the last item in an object or array
- No comments
- Numbers follow IEEE 754 double precision — integers above 2^53 lose precision
Every one of these rules is a potential footgun that JSON simply doesn't have. Trailing commas? JSON throws an error; YAML silently accepts them in some parsers. Bare words? JSON forces quotes; YAML's type inference can misinterpret them. Comments? JSON doesn't have them; YAML's comment syntax is simple but occasionally causes issues with values that look like they start a comment.
The result: JSON parse errors are loud and immediate. YAML errors are often silent structural differences — the file parses successfully but produces data you didn't intend.
When to Use JSON
JSON is the right choice in these scenarios:
- APIs and HTTP responses. JSON is the universal language of REST APIs. Every HTTP client library in every language can parse JSON. The
application/jsonMIME type is universally understood. Using YAML for an API response would require custom content negotiation that almost no client supports natively. - Database storage. PostgreSQL's
jsonbtype, MongoDB's document model, DynamoDB's attribute maps, and most NoSQL databases use JSON as their data representation. YAML is not used in any major database system. - Machine-generated configuration. When code generates a config file (a build artifact, an auto-generated schema, a terraform plan output), JSON is safer — there's no risk of generating YAML that's syntactically valid but semantically wrong due to type inference.
- Package manifests.
package.json,tsconfig.json,composer.json,manifest.json— the JavaScript/TypeScript ecosystem settled on JSON for package configuration. The lack of comments is the main limitation, partially addressed by JSONC (JSON with Comments) in VS Code configurations. - Data interchange between systems. When data crosses service or language boundaries, JSON's strict parsing semantics eliminate ambiguity. A JSON boolean
trueis always boolean regardless of which language or library parses it. A YAMLyesmight be a boolean or a string depending on the parser version.
Convert JSON files: JSON to YAML for config readability, JSON to CSV for flat data analysis, XML to JSON for API modernization.
When to Use YAML
YAML is the right choice when:
- Humans write and maintain the file. Comments, readable indentation, and no mandatory quoting make YAML significantly less error-prone for humans editing config by hand. A Kubernetes manifest that's 200 lines of JSON is painful; 200 lines of YAML is manageable.
- Comments are essential. Documenting why a value is set, not just what it is, is critical for operational configuration.
# Reduced from 100 to 25 after the 2024-Q4 OOM incidentin a YAML config file conveys context that JSON simply cannot store. JSON has no comment syntax at all. - Infrastructure configuration. Docker Compose, Kubernetes, GitHub Actions, GitLab CI, Ansible, Helm charts — the entire cloud-native ecosystem standardized on YAML. Using JSON would work technically but would be non-standard and harder to share with the community.
- Multiline string values. YAML's block scalars (
|for literal,>for folded) let you write multiline strings cleanly without escape sequences. An inline shell script or SQL query in a YAML config reads naturally; in JSON it requires\nescapes and is a maintenance nightmare. - Frequently edited by non-developers. If your config file is edited by DevOps engineers, SREs, or technical writers rather than developers, YAML's reduced punctuation lowers the error rate compared to JSON's mandatory commas and braces.
Convert YAML files: YAML to JSON for API consumption, XML to YAML to modernize legacy configs.
JSON vs YAML vs XML vs TOML
The four main structured text formats each occupy a distinct niche:
| Feature | JSON | YAML | XML | TOML |
|---|---|---|---|---|
| Comments | No | Yes | Yes (<!-- -->) | Yes (#) |
| Human readability | Moderate | High | Low (verbose) | High |
| Type system | Strings, numbers, booleans, null, arrays, objects | Same + dates, timestamps | Strings only (types via schemas) | Strings, integers, floats, booleans, dates, arrays, tables |
| Nesting depth | Unlimited | Unlimited | Unlimited | Limited (sections and tables) |
| Schemas/validation | JSON Schema | No standard | XSD, DTD, RELAX NG | No standard |
| API usage | Universal | Rare | SOAP/legacy | Never |
| Config file usage | Common | Dominant | Legacy (Maven, Spring) | Growing (Rust/cargo, Python pyproject.toml) |
| Footguns | Few (integer precision, no comments) | Many (type inference, indentation) | Namespace collisions, verbose parsing | Section vs inline table confusion |
TOML is worth mentioning as a third option for configuration files specifically. It was created explicitly to fix YAML's footguns while remaining human-readable. TOML is unambiguous about types (integers and floats have distinct syntax), supports comments, and has no indentation-based parsing. Rust's Cargo, Python's pyproject.toml, and Hugo use TOML. Its main limitation: it handles deep nesting awkwardly and is less widely supported than JSON or YAML.
XML is in decline for new projects but remains relevant for: Java/Spring configuration, Maven/Gradle build files, Microsoft Office formats (DOCX, XLSX are zipped XML), SOAP web services, and SVG. If you're dealing with XML and need JSON: XML to JSON, or for YAML: XML to YAML.
How to Convert Between JSON and YAML
JSON and YAML represent the same data model — objects (mappings), arrays (sequences), strings, numbers, booleans, and null. Conversion between them is lossless in both directions, with one exception: YAML comments are lost when converting to JSON (JSON has no comment syntax). Everything else round-trips cleanly.
JSON to YAML
Converting JSON to YAML: use ChangeThisFile's JSON to YAML converter for a no-code browser-based conversion. In Python:
import json
import yaml
with open('input.json') as f:
data = json.load(f)
with open('output.yaml', 'w') as f:
yaml.dump(data, f, default_flow_style=False, allow_unicode=True)The default_flow_style=False flag forces block style (indented, one item per line) rather than inline style ({key: value}). Both are valid YAML; block style is more readable for humans.
YAML to JSON
Converting YAML to JSON: use ChangeThisFile's YAML to JSON converter. In Python:
import yaml
import json
with open('input.yaml') as f:
data = yaml.safe_load(f) # safe_load prevents arbitrary code execution
with open('output.json', 'w') as f:
json.dump(data, f, indent=2)Use yaml.safe_load, not yaml.load — the full YAML spec allows arbitrary Python object construction via YAML tags, which is a remote code execution vector when loading untrusted YAML. safe_load restricts parsing to safe types.
Watch for type coercion: if your YAML contains yes, no, on, or off as string values (not booleans), PyYAML may convert them to boolean True/False in the JSON output. Quote these values in YAML ("yes") to preserve them as strings.
JSON and YAML are not competitors — they're tools optimized for different tasks. JSON's strictness and universality make it the right choice for APIs, databases, and any data exchange where parse ambiguity would be a bug. YAML's readability and comments make it the right choice for configuration files that humans maintain, especially in the cloud-native ecosystem where it's already the standard.
When you need to bridge between them: convert JSON to YAML to make a config more human-readable, or convert YAML to JSON when you need to pass config data to an API or store it in a database. For legacy XML formats: XML to JSON and XML to YAML conversions are also available.