JSON, YAML, XML & TOML: Data Formats Compared
A practical comparison of JSON, YAML, XML and TOML — types, comments, nesting, verbosity, conversion pitfalls, and which serialization format to use when.
Last updated: 26 July 2026
Data-serialization formats are how structured data is turned into text (or bytes) that can be stored in a file, sent over a network, or handed to another program — and then parsed back into objects. JSON, YAML, XML and TOML are the four most common text-based formats, and while they can all represent roughly the same data, each was designed for a different job. This guide compares them and helps you pick the right one.
Text vs binary formats
Serialization formats come in two families. Text formats encode data as human-readable characters: you can open the file, read it, diff it in version control and edit it by hand. JSON, YAML, XML and TOML are all text formats. Binary formats — such as Protocol Buffers, MessagePack, Avro and Parquet — encode data as raw bytes. They are smaller and faster to parse, but you need tooling to inspect them and they usually depend on a schema.
The rest of this guide focuses on the four text formats, which cover the vast majority of everyday config and interchange work.
JSON
JSON (JavaScript Object Notation) is the lingua franca of the web. It is defined by RFC 8259 and grew out of JavaScript’s object literals, but is now completely language-independent.
{
"id": 1,
"name": "Ana",
"active": true,
"tags": ["admin", "editor"],
"address": { "city": "Mumbai", "zip": null }
}
Its data model is small and unambiguous: objects (key/value maps), arrays, strings, numbers, booleans (true/false) and null. That simplicity is its strength — every language has a fast, well-tested JSON parser.
The trade-offs:
- No comments. JSON has no syntax for annotations, on purpose.
- Strict syntax. Keys must be double-quoted strings, no trailing commas are allowed, and a single stray comma breaks the whole document.
- No date or binary type — dates are conventionally strings, binary is usually base64.
Use JSON for APIs and machine-to-machine interchange, where ubiquity and strictness are exactly what you want.
YAML
YAML (“YAML Ain’t Markup Language”) is designed to be human-friendly, which makes it popular for configuration — think Kubernetes manifests, CI pipelines and Docker Compose. It is defined by the YAML 1.2 specification, and importantly YAML is a strict superset of JSON: any JSON document is also valid YAML.
id: 1
name: Ana
active: true
tags:
- admin
- editor
address:
city: Mumbai
zip: ~
YAML uses indentation rather than brackets to express nesting, supports comments (# like this), and offers anchors and aliases to reuse a block of data:
defaults: &defaults
timeout: 30
retries: 3
service_a:
<<: *defaults
name: alpha
That readability comes with real pitfalls:
- Whitespace sensitivity — a single misaligned space or an accidental tab changes the structure or fails to parse.
- Type coercion surprises — under YAML 1.1 semantics that many parsers still emulate,
no,offandyesbecome booleans, and12:30can become a number. The classic case is Norway: the country codeNOparsing asfalse. Quote ambiguous values to be safe.
Use YAML for human-edited configuration where comments and readability matter.
XML
XML (Extensible Markup Language) is the oldest of the four and the most verbose. Defined by the W3C XML specification, it wraps data in nested, named tags and remains deeply embedded in enterprise systems, SOAP web services, document formats (like DOCX and SVG) and many legacy config files.
<user id="1" active="true">
<name>Ana</name>
<tags>
<tag>admin</tag>
<tag>editor</tag>
</tags>
<address city="Mumbai"/>
</user>
XML’s distinguishing features:
- Attributes vs elements — data can live either in an attribute (
id="1") or as a child element (<name>Ana</name>). There is no single right answer, which is a frequent design debate. - Namespaces — prefixes like
xsl:let documents mix vocabularies without name clashes. - Schemas (XSD) — XML has a mature, powerful validation language (XML Schema) that formally describes and validates document structure, plus tooling like XPath and XSLT for querying and transforming.
XML is verbose and everything is a string until a schema says otherwise, but its validation and tooling ecosystem keep it common in enterprise, SOAP and document-centric contexts.
TOML
TOML (Tom’s Obvious, Minimal Language) is a config-focused format designed to be easy for humans to read and to map unambiguously to a hash table. It is defined by the TOML specification and is best known as the format behind Rust’s Cargo.toml and Python’s pyproject.toml.
id = 1
name = "Ana"
active = true
tags = ["admin", "editor"]
[address]
city = "Mumbai"
zip = ""
Its design goals:
- Obvious semantics — every value has a clear, single interpretation, so there are no YAML-style coercion surprises.
- First-class types — strings, integers, floats, booleans, and native dates and times.
- Tables —
[section]headers (and[[array-of-tables]]) express nesting without deep indentation, which stays readable as files grow. - Comments with
#.
TOML shines for application and project configuration that is edited by hand but should still parse deterministically. It gets awkward for deeply nested data, where the flat table syntax is less natural than JSON or YAML.
Side-by-side comparison
| Feature | JSON | YAML | XML | TOML |
|---|---|---|---|---|
| Comments? | No | Yes (#) |
Yes (<!-- -->) |
Yes (#) |
| Typed values | Yes (basic) | Yes (+ coercion quirks) | No (strings; types via schema) | Yes (+ dates/times) |
| Nesting | Excellent | Excellent | Excellent | Good (shallow best) |
| Verbosity | Low | Very low | High | Low |
| Typical use | APIs, interchange | Config (K8s, CI) | Enterprise, SOAP, documents | Project/app config |
Converting between formats
Because all four share a similar core data model — maps, lists and scalars — converting between them is straightforward for plain data but lossy for format-specific features:
- Comments are lost whenever you convert to JSON (which has none), and often when round-tripping through other formats.
- YAML anchors and aliases are expanded into their full value on conversion; the shared reference disappears.
- XML attributes vs elements have no native equivalent in JSON/YAML/TOML, so a converter must pick a convention (for example, prefixing attributes with
@and putting text in a#textkey). Converting back cannot always reconstruct the original structure. - Type fidelity can drift — a YAML value read as a boolean or a TOML date may become a plain string in JSON.
So expect the data to survive a conversion, but not necessarily the presentation or every type nuance.
Which should I use?
- Building or consuming an API, or moving data between programs? Use JSON — it is universal, strict and fast.
- Writing config that humans edit and want to comment? Use YAML (great for nested config like Kubernetes) or TOML (great when you value obvious, unambiguous semantics and want to avoid whitespace bugs).
- Working with enterprise systems, SOAP, documents, or needing rich schema validation? Use XML.
When in doubt: JSON for interchange, TOML for simple app config, YAML for nested config, XML when the ecosystem demands it.
References
- RFC 8259 — The JavaScript Object Notation (JSON) Data Interchange Format.
- YAML 1.2 specification — the current YAML language spec.
- XML specification — W3C Extensible Markup Language (XML) 1.0.
- TOML specification — Tom’s Obvious, Minimal Language, v1.0.0.
Try it
Convert between these formats in your browser with the Data & Transform converters — JSON ⇄ YAML, JSON ⇄ XML, JSON ⇄ TOML and more, all running entirely client-side.
Frequently asked questions
Is YAML a superset of JSON?
Yes. YAML 1.2 is a strict superset of JSON, so any valid JSON document is also valid YAML and a YAML parser can read it. The reverse is not true — YAML adds indentation-based structure, comments, anchors and more that JSON has no syntax for.
Why doesn't JSON allow comments?
Douglas Crockford deliberately removed comments from JSON so people wouldn't embed parsing directives that break interoperability. JSON is a pure data-interchange format, not a config language. If you need annotated config, use YAML or TOML; if you must comment JSON, use a superset like JSON5 or JSONC and strip comments before parsing.
JSON or TOML for configuration files?
TOML is usually the better choice for hand-edited config — it allows comments, has obvious, unambiguous semantics, and maps cleanly to key/value tables (that is why Cargo and pyproject.toml use it). JSON is fine for machine-generated config but is awkward to edit by hand because it has no comments and is strict about commas and quotes.
Is converting between these formats lossless?
Not always. The data model (objects, arrays, strings, numbers, booleans, null) converts cleanly, but format-specific features do not. Comments are lost when converting to JSON, YAML anchors and aliases are expanded, and XML attributes vs child elements have no direct JSON/YAML equivalent, so a mapping convention has to be chosen.
What is the difference between text and binary serialization formats?
Text formats (JSON, YAML, XML, TOML) are human-readable and easy to diff, debug and edit, but larger and slower to parse. Binary formats (Protocol Buffers, MessagePack, Avro, Parquet) are compact and fast but not human-readable and usually need a schema or tooling to inspect.