Skip to main content
Back to Blog

The Ultimate Guide to Data Serialization: JSON, YAML, XML, and TOON

An in-depth look at how we format and transmit data across the web, comparing JSON, YAML, XML, CSV, and the new TOON format.

Kashyap Thaker
8 min
DataJSONArchitecture
The Ultimate Guide to Data Serialization: JSON, YAML, XML, and TOON

Data serialization is the process of converting complex data structures (like objects and arrays) into a format that can be stored or transmitted across a network. Each of the formats below makes different trade-offs between readability, size, and how much structure it can express.

1. CSV: The Legacy Flat File

Comma-Separated Values (CSV) is one of the oldest and simplest formats. It excels at representing tabular data, making it the universal language of spreadsheets and legacy database exports.

  • Pros: Very little overhead; opens directly in Excel and most data analysis tools.
  • Cons: Cannot naturally represent nested or hierarchical data, has no types (everything is text), and the informal RFC 4180 does not define comments.

2. XML: The Enterprise Standard

eXtensible Markup Language (XML) dominated the early web and enterprise SOAP APIs. It wraps every value in opening and closing tags.

  • Pros: Mature schema languages and namespaces; supports comments and mixed text-and-markup documents.
  • Cons: Verbose compared with JSON for the same data, and hard to scan when deeply nested.

Tip: If you're forced to work with legacy XML APIs, use our XML to CSV converter to make the data manageable.

3. JSON: The Undisputed King of the Web

JavaScript Object Notation (JSON) took over the web because it maps directly onto JavaScript values and stays readable to humans. It is the most common payload format for REST APIs. GraphQL does not require a specific serialization format, but its specification notes that JSON is the most common.

  • Pros: A parser exists in virtually every language; compact; easy to read.
  • Cons: No comments; strict syntax (no trailing commas); no date type.

4. YAML: The DevOps Darling

YAML Ain't Markup Language is widely used for configuration files (Docker Compose, Kubernetes manifests, GitHub Actions workflows). It relies on indentation rather than braces, which makes it easy for humans to write.

  • Pros: Supports comments; minimal syntax overhead; very readable.
  • Cons: Indentation mistakes cause parse errors or silently change the structure, and unquoted values are type-guessed (see the pitfalls below).

5. TOON: The High-Performance Challenger

Token-Oriented Object Notation (TOON) is a newer, compact encoding of the JSON data model aimed at LLM input, where tokens cost money. For arrays of uniform objects it declares the field names once in a header and then lists one row per object, so the keys are not repeated. The project's README notes that JSON can be the more efficient choice for deeply nested or non-uniform data.

Compare the size of your own data with our JSON to TOON converter.

Side-by-Side Comparison

The same question keeps coming up: can the format nest data, can humans annotate it, and what is it actually good at? Here is the short version.

FormatNestingCommentsBest fit
CSVNo (flat rows)Not defined in RFC 4180Tabular exports, spreadsheets
XMLYesYes (<!-- -->)Documents, SOAP, schema-driven exchange
JSONYesNoWeb APIs, general data interchange
YAMLYesYes (#)Human-edited configuration
TOONYes (indentation)Full-line # comments only; decoders discard themUniform arrays sent to LLMs

Text Formats vs Binary Formats

Everything above is a text format: you can open it in an editor, diff it in Git, and paste it into a bug report. Binary formats such as Protocol Buffers, MessagePack, Avro and CBOR (RFC 8949) trade that readability for compact encodings. They need a library on both ends, some (Protocol Buffers, Avro) also need a schema, and you cannot read them in a terminal without a decoder.

A reasonable rule: start with a text format, measure, and move to binary only when payload size or parse time is a demonstrated bottleneck, typically between services you control on both sides. For public APIs, readable text wins because every client language already ships a JSON parser.

Pitfalls That Cross Every Format

Numbers and Precision

JSON (RFC 8259) defines a number grammar but not a precision, so each parser decides. JavaScript stores every number as a 64-bit float, which means integers above Number.MAX_SAFE_INTEGER (9007199254740991) silently change. Database IDs, snowflake IDs and large counters should travel as strings.

JSON.parse('{"id":9007199254740993}').id
// 9007199254740992

JSON.parse("12345678901234567890")
// 12345678901234567000

JSON.stringify({ p: 0.1 + 0.2 })
// {"p":0.30000000000000004}

CSV has no number type at all, so 02134 (a ZIP code) and 1e3 are just text until some tool guesses.

Values the Format Cannot Express

JSON has no undefined, NaN, Infinity, date, or BigInt type. In JavaScript, JSON.stringify drops or rewrites them, and often without an error:

JSON.stringify({ a: undefined, b: () => 1, c: NaN, d: Infinity, e: new Date(0), f: [undefined] })
// {"c":null,"d":null,"e":"1970-01-01T00:00:00.000Z","f":[null]}

JSON.stringify({ n: 1n })
// TypeError: Do not know how to serialize a BigInt

Dates are the classic case: send ISO 8601 strings and parse them explicitly on the other side. Our timestamp converter helps when you are moving between Unix time and ISO strings.

Encoding

RFC 8259 requires JSON text exchanged between systems outside a closed ecosystem to be UTF-8. XML declares its encoding in the prolog and defaults to UTF-8 or UTF-16. CSV declares nothing, which is why spreadsheet exports so often arrive as Windows-1252 and turn accented names into garbage. When binary data must ride inside a text format, it is typically Base64-encoded; see our Base64 guide.

Large Files and Streaming

A single JSON array or XML document usually has to be fully read before it is useful, which strains memory on big exports. Two common workarounds: newline-delimited JSON (one complete JSON value per line, often called NDJSON or JSON Lines), where each line can be parsed independently, and CSV, which is naturally streamable row by row. For XML, use a streaming (SAX-style) parser instead of loading a full DOM.

'{"a":1}\n{"a":2}'.split("\n").map((line) => JSON.parse(line))
// [ { a: 1 }, { a: 2 } ]

Security Considerations

  • YAML: some YAML libraries support language-specific tags that can construct arbitrary objects. Only parse untrusted YAML with a safe loader that restricts input to plain data types.
  • XML: parsers that resolve external entities (XXE) or expand nested entities (the "billion laughs" attack) can leak files or exhaust memory. Disable DTD processing and external entity resolution for untrusted input.
  • JSON: parse it with JSON.parse, never eval. RFC 8259 says object names SHOULD be unique and that the behavior of software receiving duplicates is unpredictable. JavaScript keeps the last one, so {"a":1,"a":2} becomes { a: 2 }, and other parsers may disagree.
  • CSV: a cell that starts with =, +, - or @ (OWASP also lists a leading tab or carriage return) can be executed as a formula when opened in a spreadsheet. If you generate CSV from user input, neutralise those leading characters.

A Quick Decision Checklist

Which Should You Use?

For almost all web APIs, stick to JSON. If you are writing configuration files intended for humans to edit, use YAML. If you are feeding large arrays of uniform objects to a language model, consider TOON; for plain bandwidth savings, compress your JSON with gzip or Brotli. And when the consumer is a spreadsheet or finance team, you will need CSV.

Frequently Asked Questions

What is data serialization?

Serialization turns an in-memory structure into a sequence of bytes or characters that can be saved or sent. Deserialization reverses it. JSON, YAML, XML and CSV are all serialization formats; they differ in what structures they can represent and how readable they are.

Is JSON a subset of YAML?

Since YAML 1.2, valid JSON is intended to be valid YAML, so most JSON documents load in a YAML 1.2 parser. Older YAML 1.1 parsers and edge cases such as duplicate keys can behave differently, so do not rely on it for strict validation.

Why did JSON replace XML for APIs?

JSON maps directly onto the objects, arrays, strings and numbers that programming languages already have, and it needs less markup per value. XML remains strong where you need schemas, namespaces, mixed text-and-markup documents, or compatibility with existing enterprise systems.

Which format is the smallest?

For flat, uniform rows, CSV is usually the most compact text format because keys appear only once. For nested data, JSON is more compact than XML. Gzip or Brotli compression narrows the differences considerably, so measure on your real payloads rather than guessing.

Written by Kashyap Thaker, founder of 11Vertex.

Spotted an error? hello@kashyap.im · How we write this site