The impedance mismatch: trees vs. tables
JSON and CSV describe data in fundamentally different shapes. JSON is hierarchical: objects can nest inside objects, arrays can hold more objects, and depth is unbounded. CSV is flat and tabular: a fixed set of columns and one record per row, like a spreadsheet. Converting from one to the other means deciding how to project a tree onto a grid — and that decision is where most of the work lives.
The good news is that a huge amount of real-world JSON already fits a table neatly. If your data is a list of similar records — users, orders, log entries — the conversion is almost mechanical.
The ideal input: an array of flat objects
The cleanest source for CSV conversion is a JSON array of flat objects, where every object shares the same keys and every value is a simple scalar (string, number, boolean, or null). Each object becomes one row, and the object keys become the header row.
[
{ "id": 1, "name": "Ada", "active": true },
{ "id": 2, "name": "Linus", "active": false }
]
This maps directly to:
id,name,active
1,Ada,true
2,Linus,false
When objects have different keys, a good converter takes the union of all keys as the header and leaves missing cells empty. Keeping a consistent key order also keeps your columns stable between exports.
Handling nested objects and arrays
Real JSON is rarely perfectly flat. When a value is itself an object or an array, you have two main strategies:
- Flatten — promote nested keys into compound column names using a separator, so
{ "address": { "city": "Oslo" } }becomes a column namedaddress.city. This keeps the data queryable in a spreadsheet but can produce many columns. - Stringify — serialize the nested value back to a JSON string and store it in a single cell, e.g. a
tagsarray becomes the literal text["a","b"]. This is compact but the cell is no longer tabular data.
For arrays of varying length (one user has 2 tags, another has 5), flattening into tags.0, tags.1, … leads to ragged, sparse columns. Stringifying is usually the more predictable choice there. Pick whichever matches how the CSV will be consumed downstream.
CSV quoting and escaping rules
CSV looks simple until a value contains a comma. The widely followed convention (RFC 4180) is straightforward:
- A field that contains a comma, a double quote, or a line break must be wrapped in double quotes.
- Any double quote inside a quoted field is escaped by doubling it (
"becomes""). - Fields without special characters can be left bare.
So the value Hello, "world" is written as "Hello, ""world""". A value containing a newline stays on what looks like multiple visual lines but is still a single field because it's quoted. Getting this exactly right by hand is error-prone, which is why a tested library matters.
Parsing CSV back to JSON
Going the other direction, the first row is treated as the header, supplying the keys, and every subsequent row becomes an object. A parser must respect the same quoting rules in reverse — unwrap quoted fields, collapse doubled quotes, and keep quoted newlines inside the cell rather than splitting on them.
CSV has no types: every cell is text. Many converters offer optional type inference, turning 42 into a number, true/false into booleans, and empty cells into null or empty strings. This is convenient but lossy — a ZIP code like 01234 can lose its leading zero, and a long ID can hit floating-point limits. If exact text matters, keep inference off and treat everything as strings.
A note on Excel and the UTF-8 BOM
If your data contains non-ASCII characters (accents, emoji, non-Latin scripts) and you plan to open the file in Microsoft Excel, prepend a UTF-8 byte order mark (BOM) — the bytes EF BB BF — to the start of the file. Without it, older Excel versions may misread UTF-8 as a legacy encoding and mangle characters like café into café. The BOM is invisible to the user but tells Excel the file is UTF-8. Many other tools ignore or strip it, so add it only when targeting Excel.
Worked example
Given this JSON array with a comma and a quote in the data:
[
{ "name": "Acme, Inc.", "note": "She said \"hi\"", "score": 9.5 },
{ "name": "Globex", "note": "ok", "score": 7 }
]
The correct CSV output is:
name,note,score
"Acme, Inc.","She said ""hi""",9.5
Globex,ok,7
Notice how Acme, Inc. is quoted because of its comma, the embedded quotes in the note are doubled, and the plain values stay unquoted.
Convert it instantly with Formatly
Formatly's JSON to CSV Converter handles all of this for you. It's built on PapaParse, a battle-tested CSV library that gets quoting, escaping, and newline handling right in both directions, so you don't have to implement RFC 4180 yourself. Paste a JSON array, get clean CSV, and convert CSV back to JSON when you need to. Best of all, the conversion runs entirely in your browser — your data is never uploaded to a server, which makes it safe for client lists, exports, and other sensitive datasets.