Skip to main content
PocketToolz

JSON, YAML or CSV: which one, and what each gets wrong

Why JSON is strict on purpose, the YAML values that silently change meaning, and the number precision bug that quietly corrupts large IDs.

10 min read

JSON, YAML and CSV all store structured data as text, and they are not interchangeable. Each was designed around a different priority, and picking the wrong one usually shows up later as a class of bug that the right one would have made impossible.

The short version: JSON for anything a machine writes and another machine reads, YAML for anything a human has to edit by hand, and CSV only for flat tables of rows.

JSON is strict on purpose

JSON’s value is that it barely has any features. Objects, arrays, strings, numbers, booleans and null — that is the whole format. There is nothing to configure and very little to disagree about, which is why it won.

Four rules trip people up, and all four are deliberate:

No trailing commas. [1, 2, 3,] is invalid. Most languages allow it; JSON does not.

Double quotes only, on both strings and keys. {'a': 1} is not JSON.

No comments. This one is genuinely inconvenient, and it is the single most common reason a config file that started as JSON ends up as YAML.

No NaN or Infinity. They are not representable, so serialisers either error or quietly turn them into null.

When a file will not parse, it is almost always one of those. The JSON formatter will point at the offending character, and the tree viewer is the faster way to find your way around a large response once it is valid.

The number problem nobody warns you about

JSON numbers have no declared precision, and most parsers read them as 64-bit floats. That is fine until a value exceeds about 9 quadrillion — roughly 253 — at which point it starts silently losing accuracy.

This is not hypothetical. Large database IDs, Twitter-style snowflake IDs, and anything counting nanoseconds all land in that range, and the failure is quiet: the ID comes back off by one and nothing errors. The fix is to send large identifiers as strings.

YAML is for humans, and that costs something

YAML exists because editing JSON by hand is unpleasant. It has comments, does not need quotes or braces, and uses indentation for structure — all of which make a config file far more readable.

The cost is that YAML is a much larger specification with room for surprises. Two are worth knowing about.

Indentation must be spaces. Tabs are forbidden outright, and since a tab and some spaces look identical, this produces errors that are invisible on screen.

Unquoted values get interpreted. In older YAML versions no parses as boolean false — which famously turned the country code for Norway into false — and 1.20 becomes the number 1.2, dropping the trailing zero. A version number like 1.10 becomes 1.1, which is a different version. Quote anything that is meant to stay a string.

Because YAML is a superset of JSON, any valid JSON is already valid YAML. Converting between the two is mostly lossless in that direction; going back loses comments, since JSON cannot represent them.

CSV is simpler than it looks, and messier

CSV is rows of values separated by commas. There is no schema, no types, and no nesting — everything is text, and the reader decides what it means.

The messiness comes from values containing the separator. The convention is to wrap those in double quotes, and to escape a literal quote by doubling it, so a field containing He said "hi" is written "He said ""hi""". Hand-rolled parsers that split on commas break the first time they meet a quoted field, which is why using a real parser matters more here than the format’s simplicity suggests.

The other hazard is spreadsheet software, which will helpfully reformat your data on open. Leading zeros disappear from postcodes and product codes, long numbers become scientific notation, and anything that looks remotely like a date becomes one. If a CSV is going to be opened in Excel, that is a property of the file you have to design around.

For moving a table into something structured, the CSV to JSON converter handles the quoting rules properly and goes in both directions.

Choosing between them

Use JSON for APIs and anything machine-generated. It is universally supported, unambiguous, and its strictness is what makes it safe to pass between systems that know nothing about each other.

Use YAML for configuration a person maintains, where comments and readability are worth the extra footguns. This is why CI pipelines and container orchestration settled on it.

Use CSV for flat tabular data that has to open in a spreadsheet. The moment your data has nesting or optional fields, it is the wrong format and forcing it will hurt.

Working with them day to day

Two jobs come up constantly. Comparing two responses to find what changed is far easier with a structural diff than a text one, because key order does not matter in JSON but does to a line-based diff.

And if you are consuming an API in a typed language, generating types from a sample response is quicker than writing them out and much less likely to drift from what the server actually sends.

For the other text format that shows up in the same work, formatting a SQL query makes the structure of a long statement visible in a way that a single-line query never is.

Tools for this

Everything below runs in your browser. Nothing is uploaded.