JSON vs XML vs YAML: Choosing the Right Data Format
JSON, XML, and YAML can all describe the exact same data — a user record, a config file, an API payload — but they optimize for different things. Picking the wrong one for a given job usually shows up later, as unreadable config diffs or a parser that can't express what you need. This guide compares the three head-to-head on syntax, size, speed, and feature set, and gives a concrete rule of thumb for each.
The same data, three ways
Here's one small object represented in all three formats. Comparing them side by side is the fastest way to see what each format actually trades off.
{
"user": {
"name": "Ada Lovelace",
"roles": ["admin", "editor"],
"active": true
}
}user:
name: Ada Lovelace
roles:
- admin
- editor
active: true<user active="true">
<name>Ada Lovelace</name>
<roles>
<role>admin</role>
<role>editor</role>
</roles>
</user>Same three fields, three very different amounts of punctuation. That difference is the whole story: JSON is the most machine-friendly, YAML is the most human-friendly to write by hand, and XML is the most expressive when the document itself needs structure beyond simple key/value data.
Where JSON wins
JSON is the default for a reason: it maps directly onto the data structures every mainstream language already has (objects/dicts and arrays/lists), so parsing it round-trips into native types with zero ambiguity. It has no comments, no multiple ways to write the same value, and no whitespace sensitivity — which sounds limiting but is exactly what makes it fast to parse and safe to generate programmatically.
Use JSON for anything machine-to-machine: REST and GraphQL API payloads, data passed between services, anything stored in a document database (MongoDB, PostgreSQL's JSONB), and any config that's primarily read and written by code rather than edited by hand.
Where YAML wins
YAML is a strict superset of JSON's data model with a much friendlier syntax for humans: no closing brackets to count, comments with #, and indentation instead of punctuation. That's exactly what you want for files a person edits directly and re-reads in a diff — CI pipelines (GitHub Actions, GitLab CI), Kubernetes manifests, and application config.
The trade-off is that YAML's flexibility is also its biggest footgun: indentation errors silently produce a different structure instead of a parse error, and unquoted values like `no`, `yes`, `on`, and dates can be auto-converted to booleans or timestamps you didn't intend (the infamous 'Norway problem', where the country code NO becomes the boolean false). Quote your strings when there's any ambiguity.
Where XML wins
XML looks like legacy overhead next to JSON, but it does things neither JSON nor YAML can: attributes alongside element content, mixed content (text and elements interleaved, like HTML), namespaces for combining vocabularies from different sources, and mature schema validation (XSD) plus transformation (XSLT) tooling that predates JSON by a decade.
That's why XML persists in document-centric domains — SOAP APIs, SVG, DOCX/XLSX (which are ZIP files full of XML), and enterprise systems (banking, healthcare, government) with existing XSD-validated pipelines nobody is rewriting. If your data is genuinely document-shaped (think 'a paragraph with a bolded span in the middle') rather than record-shaped, XML is often still the better fit.
Size and parsing speed
For the same record-shaped data, YAML is typically the smallest on disk, JSON lands within a few percent of it, and XML runs roughly 30–40% larger than JSON once you count closing tags and either attributes or wrapper elements. A 1 KB JSON payload is usually around a 950-byte YAML file and a 1.3–1.4 KB XML document. Those gaps matter for files on disk, payloads embedded in bundles, and anything stored uncompressed; over HTTP they matter much less.
The reason is compression: gzip and brotli — which nearly every production API and CDN enables — squash repeated punctuation and indentation to almost nothing, and all three formats compress well. After brotli, the minified-JSON and pretty-YAML versions of the same data usually land within a few percent of each other. Parsing tells a similar story: JSON.parse is a native, heavily optimized code path in every browser and in Node, YAML needs a library and a far heavier grammar, and XML sits in between. None of it is measurable for config parsed once at startup; on a hot path, JSON's cheap parser is a real advantage.
Comments, multi-document files, and other sharp edges
Comments: YAML has them (#), XML has them (<!-- -->), JSON does not — a deliberate choice. If documents could differ only by a comment, implementations that strip or keep comments would disagree about equality, which breaks signatures, hashes, and cache keys.
Multi-document files: YAML separates documents with ---, so one file holds a stream of records; XML permits exactly one root element; JSON defines a single value per document, with JSON Lines — one minified document per line — as the ecosystem convention for streams. YAML also has anchors and aliases (&anchor / *alias) for reuse, which JSON has no equivalent for.
Each format has a characteristic sharp edge. YAML's indentation sensitivity and implicit type coercion (the Norway problem) mean a file can parse successfully into a different structure than you intended. XML's entity expansion is an attack surface (the XXE vulnerability class) in misconfigured parsers, and namespaces add verbosity JSON never has. JSON's own edge is milder than both — no comments, no date type, integer precision capped at 2^53 — which is precisely why it's the safest of the three to accept from untrusted sources.
Converting between formats
Since all three describe the same object/array/string/number/boolean/null data model (XML's attributes and mixed content are the one thing that doesn't map cleanly), converting between JSON, YAML, and XML is usually mechanical for anything record-shaped. JsonForge's JSON to YAML, YAML to JSON, JSON to XML, and XML to JSON tools handle the conversion in the browser, which is useful when you're migrating a config file's format or need to hand a YAML-only teammate a JSON export.
XML is the awkward direction: attributes versus child elements is a distinction JSON doesn't have, so every converter adopts a convention — attributes get an @ prefix, or land in a fixed sub-object — and a document round-tripped through it comes back a different shape. JSON ⇄ YAML conversion, by contrast, is essentially lossless in both directions.
FAQ
- Is YAML just JSON with different syntax?
- Almost — YAML 1.2 is a superset of JSON, meaning any valid JSON document is also valid YAML. But YAML adds features JSON doesn't have (comments, anchors/references, multi-document files) and its own parsing quirks (implicit type conversion), so the reverse isn't true: not all YAML is valid JSON.
- Why do Kubernetes and CI tools use YAML instead of JSON?
- Because those files are hand-written and hand-reviewed constantly. YAML's lack of brackets and support for comments make it far more pleasant to read and diff in a pull request than the equivalent JSON, even though JSON would parse identically.
- Why does XML still exist if JSON is simpler?
- XML supports things JSON structurally cannot: attributes on elements, mixed text/element content, namespaces, and schema validation via XSD. Formats built on top of XML — SVG, DOCX, XLSX, SOAP — rely on exactly those features, which is why XML hasn't disappeared even though JSON won for typical REST APIs.
- What is the YAML 'Norway problem'?
- In YAML, unquoted `NO` (Norway's country code) is parsed as the boolean `false`, because YAML auto-converts unquoted `no`/`yes`/`on`/`off` to booleans. It's a well-known gotcha — always quote country codes, version strings, and anything that looks like a boolean or number but is meant as a literal string.
- Why doesn't JSON support comments?
- Because comments would break the guarantee that equal data has exactly one serialized form. JSON is an interchange format generated and compared by machines — with comments, two parsers can disagree about whether two documents are identical, which breaks signing, hashing, and caching. JSONC and JSON5 exist for hand-edited config, but they're supersets, not JSON.
Try these tools
JSON to YAML →
Convert JSON to YAML and back, with type inference and clean formatting.
YAML to JSON →
Convert YAML configs — CI pipelines, Kubernetes manifests, OpenAPI specs — into JSON, with precise parse errors.
JSON to XML →
Convert JSON to XML and back, with automatic root-element wrapping.
XML to JSON →
Convert XML — SOAP responses, RSS feeds, legacy exports — into JSON, keeping attributes and reporting parse errors.
Related articles
What is JSON? A Complete Beginner's Guide →
JSON (JavaScript Object Notation) is the lightweight data-interchange format behind nearly every API, config file, and NoSQL database. Learn the syntax, the six data types, how parsing behaves in code, and the mistakes everyone makes hand-writing it.
The History of JSON: From 2000 to Industry Standard →
Trace JSON from Douglas Crockford's idea in 2001, through Yahoo's adoption, to becoming the ECMA-404 standard that powers 90% of modern APIs.
The Complete JSON Schema Guide (Draft 7) →
JSON Schema is the standard for describing and validating JSON structure. Learn the core keywords, build a real API schema, compose and reuse schemas with $ref, and run validation in code with Ajv.