JSON vs CSV: what each format can hold, and which to pick
Two plain-text formats, often offered by the same download screen, and not interchangeable. One stores a shape; the other stores a table. Here is the same data written both ways, a size comparison we measured, and what disappears when JSON is flattened into CSV.
Short answer
- JSON stores a shape: objects inside objects, arrays, and values that are explicitly a number, a boolean or null.
- CSV stores one flat table of rows and columns, and every value in it is text.
- So: pick CSV for rows headed to a spreadsheet, JSON when the structure matters. Going from JSON to CSV always throws something away.
Get Sonnet free For reading the JSON one on your phone.
What’s the difference between JSON and CSV?
Both are plain text, and both open in any text editor. The difference is what each one is allowed to say.
JSON describes values together with the structure around them. The specification Python’s json module implements — RFC 7159 and ECMA-404 — gives it seven things to work with: object, array, string, number, true, false and null. An object holds named values, an array holds an ordered list, and either can contain the other to any depth. If you are new to the format, what a JSON file actually is covers the basics first.
CSV describes a grid. The first line normally names the columns, and every line after it is one record. A field that contains a comma or a line break has to be wrapped in double quotes, and a quote inside a quoted field is written twice — Go’s encoding/csv, which implements RFC 4180, puts it as “Within a quoted-field a quote character followed by a second quote character is considered a single quote.”
Then there is the part that surprises people: CSV carries no types at all. Python’s csv module returns each row “as a list of strings”, and its documentation notes that “No automatic data type conversion is performed” unless you explicitly ask for it. The number 42, the text 42 and a product code 42 are the same two characters in the file. Whatever opens it decides what they mean.
And there is no single CSV. Python’s documentation says so directly: “CSV format was used for many years prior to attempts to describe the format in a standardized way in RFC 4180,” and “The lack of a well-defined standard means that subtle differences often exist in the data produced and consumed by different applications.” Separator, quote character and line ending all vary between the programs that write them.
| JSON | CSV | |
|---|---|---|
| Shape | Nested — objects and arrays, any depth | Flat — one table of rows and columns |
| Value types | string, number, true, false, null | None. Every field is text |
| Field names | Repeated as keys on every record | Written once, in the header row |
| Specification | RFC 7159 and ECMA-404 | RFC 4180, written to describe a format already in use |
| Usually opened with | A JSON viewer or a code editor | A spreadsheet |
Format facts from the Python json and csv module documentation and Go’s encoding/csv source, read 26 October 2026.
Which file is smaller, JSON or CSV?
CSV, by a lot — until you compress it, and then barely at all. We generated one dataset and wrote it twice to check: 10,000 records of five fields each (an id, a timestamp, a title, an artist and a play count), identical values in both files.
- CSV: 653 KB
- JSON, minified: 1,122 KB — 1.7× the CSV
- JSON, indented: 1,474 KB — 2.3× the CSV
The overhead is the keys. CSV writes the five field names once, in the header row. JSON repeats all five on every one of the 10,000 records, each in quotes, with a colon and a comma around it. Indenting adds the rest; if that is what you are looking at, formatting and minifying JSON is the same data either way.
Then we zipped all three. The CSV came to 228 KB and the minified JSON to 253 KB — about 11% apart, not 70%. Compression is very good at repeated text, and repeated keys are the most repetitive thing in the file. So if your data arrives zipped, as exports usually do, the format barely changes the download. It matters afterwards, when a phone has to hold the unzipped file: see opening a large JSON file on Android for where those limits fall.
What gets lost when you turn JSON into CSV?
Here is one record with the kinds of values CSV has no slot for:
[
{
"id": 1,
"name": "Ava",
"tags": ["pro", "beta"],
"address": { "city": "Lisbon", "zip": "1000-001" },
"active": true,
"nickname": null
}
]
Flattened into CSV, one reasonable result is this:
id,name,tags,address.city,address.zip,active,nickname
1,Ava,"pro,beta",Lisbon,1000-001,true,
Everything is still readable, and four separate things have been given up:
- The array became a string.
tagsheld two values; the cell now holds the eight characterspro,beta, quoted so the comma doesn’t split the row. Nothing in the file says it should be split back into two. - The nested object became a naming convention.
address.cityis one tool’s choice. Another writesaddress_city, and a third drops the nesting and keeps onlycity. None of them is wrong, because CSV has no rule here. - The types became text.
truewas a boolean and is now four letters.1000-001was a string, and nothing left in the file still says so. - Null became indistinguishable from empty. The trailing comma leaves a blank cell, and a blank cell is also what an empty string looks like.
The reverse direction is the easy one. A CSV is already an array of flat records, so turning it into JSON needs no decisions beyond which columns are numbers. That asymmetry is the whole of it: CSV to JSON is a conversion, JSON to CSV is an edit.
When to pick JSON, and when to pick CSV
If a download screen offers you both, decide by what you are going to do next, not by which file is smaller.
- Pick CSV when the data is genuinely a table — one row per thing, the same columns every time — and a person or a spreadsheet is going to sort and total it.
- Pick JSON when records have lists inside them, optional fields, or sections nested under other sections. A CSV of that data is a lossy summary of it.
- Pick JSON when a program will read it, including anything you might write yourself later. Types and structure arrive intact instead of being guessed.
Most personal data exports on this blog are JSON for exactly that reason: a message or a post has lists and optional fields inside it. Which Google Takeout files are JSON walks through one export file by file.
How to tell which one you’re holding
- The extension, if your file manager shows it:
.jsonor.csv. Phones often hide it, and an attachment can arrive as.txtor with no extension at all. - The first character. Open it as text and look: JSON starts with
{or[and its values are written"name": value. CSV starts straight into a line of words separated by commas, with no braces and no colons. - The error message. If an app says the JSON is invalid at the very first character, you may simply have handed a CSV to a JSON app. What an invalid JSON error means covers the rest of the causes.
How to open each one on an Android phone
They need different apps, and it is worth saying plainly which one we make.
CSV goes to a spreadsheet. Google announced in January 2016 that the Sheets app for Android could open, view and edit .csv files, and spreadsheet apps have been the normal home for them since. Sonnet is a JSON viewer and editor, not a CSV viewer, and sending you to the right app costs us nothing.
JSON goes to a JSON app. Sonnet opens a JSON file as a collapsible tree you can fold section by section, edits values with a tap, and works offline with no ads and no account. Files up to 20 MB open for free as formatted text, with the full tree for JSON up to about 2 MB; the one-time Sonnet Pro unlock raises that to 50 MB files, a tree up to about 30 MB, and search. If a file is slightly broken, Sonnet repairs missing and trailing commas and unclosed brackets as it opens it and tells you it did — it will not invent data that is missing. The JSON apps for Android, compared covers the alternatives, ours included.
If the file turned out to be JSON
Sonnet opens JSON as a collapsible tree, edits it with a tap, formats or minifies it, and works offline. No ads, no account. Free on Google Play, with an optional one-time Pro unlock for bigger files and search.