The main difference between YAML and JSON is who reads the file. JSON is the default for APIs and data sent between programs. YAML is the default for config files that people edit by hand. Both describe the same kind of data, but they differ in comments, data types, whitespace rules and security.
This guide compares them feature by feature, shows the same data in both formats, and gives you a simple rule for choosing. To convert between the two, the JSON ⇄ YAML converter works in both directions in your browser.
YAML vs JSON at a glance
Both formats use the same data model: scalars (strings, numbers, booleans, null), sequences (arrays or lists) and mappings (objects or dictionaries). The difference is in how each one writes that model down and where people use it.
| Aspect | JSON | YAML |
|---|---|---|
| Structure | Braces and brackets | Indentation (significant whitespace) |
| Comments | Not supported | Supported (# comment) |
| Quotes on keys | Required (double quotes) | Usually optional |
| Anchors / references | No | Yes (& and *) |
| Parse speed | Very fast | Slower |
| Primary use | APIs, data interchange | Configuration files |
| Superset relationship | Valid JSON is almost always valid YAML | Most YAML is not valid JSON |
The last row surprises people. YAML 1.2 was designed as a superset of JSON, so most JSON documents parse as YAML. The reverse does not hold.
Syntax: braces vs indentation
JSON marks structure with punctuation. Objects go in braces, arrays go in brackets, and every key is a double-quoted string followed by a colon. JSON is verbose, but a parser never has to guess where a block starts or ends.
YAML uses indentation instead. The number of spaces before a line sets its nesting level. List items start with a dash, and keys rarely need quotes. The result reads like an outline, which is why people prefer it for files they edit by hand.
{
"service": "api",
"port": 8080,
"replicas": 3,
"features": ["auth", "logging"],
"database": {
"host": "db.internal",
"ssl": true
}
}service: api
port: 8080
replicas: 3
features:
- auth
- logging
database:
host: db.internal
ssl: trueAnchors, aliases, and JSON as valid YAML
YAML has anchors and aliases, which JSON lacks. They let you define a block once and reuse it. With merge keys (<<), they remove a lot of repetition from large config files.
defaults: &defaults
timeout: 30
retries: 3
production:
<<: *defaults
host: prod.example.com
staging:
<<: *defaults
host: staging.example.comJSON has no equivalent, so you duplicate shared values or resolve them in your application. In the other direction, YAML 1.2 is a JSON superset, so you can paste a JSON document into a YAML file and most parsers accept it. That helps with gradual migration. The relationship only runs one way: valid JSON is valid YAML, but YAML that uses comments, anchors or indentation is not valid JSON.
Tooling, speed and security
Every major language ships a fast, well-tested JSON parser in its standard library. YAML parsing is slower because the grammar is much more complex, and library quality varies. For high-throughput APIs, that speed gap matters.
Security is the bigger difference. Some YAML libraries can build arbitrary language objects from tags like !!python/object. That turns an untrusted YAML file into remote code execution. JSON has no such feature by design.
import yaml
# UNSAFE: can instantiate arbitrary objects
data = yaml.load(untrusted, Loader=yaml.Loader)
# SAFE: only plain data types
data = yaml.safe_load(untrusted)With JSON, checking structure matters more than parser safety. A JSON validator or a schema check (see the JSON Schema guide) catches malformed payloads before they reach your code.
When to use each, and how to convert
The simple rule is about audience. If a machine is the main reader, use JSON. If a person is the main editor, use YAML.
- Use JSON for REST and GraphQL payloads, message queues, browser to server data, log lines (NDJSON), and anything that is performance-sensitive or comes from untrusted sources.
- Use YAML for application config, CI/CD pipelines, Kubernetes manifests, Docker Compose, and any file a developer edits by hand and wants to comment.
- Consider TOML for simple flat config, or JSON5/JSONC when you want comments but need to stay close to JSON.
Many stacks need both. Your build might turn YAML config into JSON, or you might want to skim a JSON API response as YAML. Plain data converts without loss. Comments and anchors do not survive the round trip, because JSON cannot represent them.
If your data is more tabular than nested, another format may fit better. Compare the trade-offs in JSON vs CSV and JSON vs XML.
Comments, data types and readability
Comments
Developers miss comments in JSON more than any other feature. The JSON spec has no comment syntax, so you cannot note in a config file why a value was chosen. YAML supports comments with #, which is a big reason it wins for configuration.
If you need comments but must ship JSON, look at JSONC or JSON5, covered in JSON5, JSONC, and NDJSON explained.
Data types and implicit typing
JSON has six explicit types: string, number, boolean, null, array and object. See JSON data types explained for details. YAML supports the same types but guesses them from unquoted text, which leads to subtle bugs. The best-known case is the 'Norway problem'. YAML 1.1 parsers read the unquoted value NO as the boolean false.