Converting JSON to CSV means turning an array of objects into rows and columns: each object becomes a row, and each key becomes a column header. The fastest way is a converter tool like our JSON to CSV converter, but you can also do it in a handful of lines of JavaScript or Python. The only part that takes real thought is flattening nested data, because CSV is flat and JSON often is not.
The shape of the problem
CSV is a grid: a fixed set of columns, one row per record. JSON is a tree: objects can contain other objects and arrays to any depth. So the clean case is an array of flat objects that all share the same keys. That maps to a table directly:
[
{ "id": 1, "name": "Ada", "role": "admin" },
{ "id": 2, "name": "Linus", "role": "user" }
]
id,name,role
1,Ada,admin
2,Linus,userThe header row comes from the object keys, and every object contributes one data row. Everything else in this guide is about getting messier data into that shape.
Method 1: an online converter
If you just need the file, paste your JSON into a converter and copy the result. Our JSON to CSV tool runs entirely in your browser, so your data never leaves your device, and it handles the header row, quoting, and escaping for you. This is the right choice for a one-off export or a quick check.
Method 2: JavaScript
When the conversion is part of a script or app, a small function does the job. The important detail is escaping: any value that contains a comma, a double quote, or a newline must be wrapped in double quotes, and any double quote inside it must be doubled.
function toCsv(rows) {
if (rows.length === 0) return "";
const headers = Object.keys(rows[0]);
const escape = (value) => {
const s = value == null ? "" : String(value);
// Quote if the value contains a comma, quote, or newline.
if (/[",\n]/.test(s)) {
return '"' + s.replace(/"/g, '""') + '"';
}
return s;
};
const lines = [
headers.join(","),
...rows.map((row) => headers.map((h) => escape(row[h])).join(",")),
];
return lines.join("\n");
}
// const data = [{ id: 1, name: "Ada" }, { id: 2, name: "Linus" }];
// console.log(toCsv(data));This assumes every object shares the first object’s keys. If your objects have differing keys, build the header from the union of all keys first, then fill missing values with an empty string.
Method 3: Python
Python’s standard library already knows how to write CSV, quoting and escaping included. csv.DictWriter is the direct fit for a list of dictionaries:
import csv, json
data = json.loads('[{"id": 1, "name": "Ada"}, {"id": 2, "name": "Linus"}]')
with open("out.csv", "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=data[0].keys())
writer.writeheader()
writer.writerows(data)Passing newline="" when opening the file is important on Windows: it stops Python from turning each line ending into a doubled blank line.
Handling nested data
Real JSON often nests. Say each record has an address object:
{
"id": 1,
"name": "Ada",
"address": { "city": "London", "zip": "EC1" },
"tags": ["admin", "beta"]
}A nested object is usually flattened into dot-notation columns, so address.city and address.zip become their own headers:
id,name,address.city,address.zip,tags
1,Ada,London,EC1,"admin, beta"Arrays are the genuinely ambiguous case. You have two reasonable options, and which is right depends entirely on what will read the file:
- Join into one cell. Combine the items into a single value like
"admin, beta". Simple, and fine when the array is just a label list. - Explode into columns or rows. Give each item its own column (
tags.0,tags.1) or repeat the record across multiple rows, one per item. Better when each item is a full record in its own right.
There is no universally correct choice, which is exactly why nested JSON does not convert “automatically” without you deciding this.
Escaping and spreadsheet gotchas
- Commas, quotes, and newlines inside a value must be quoted, or the columns shift. Both snippets above (and any good tool) handle this.
- Leading zeros in values like ZIP codes or IDs are often dropped when a spreadsheet reads the cell as a number. Keep them as text if they matter.
- A leading =, +, or - can make Excel treat a cell as a formula. If your data can contain these, prefix the value or import as text to avoid formula injection.
- Encoding. Save as UTF-8 so accented characters and symbols survive the trip into a spreadsheet.
For a quick, private conversion with the quoting and flattening already handled, paste your data into our free JSON to CSV converter. It runs in your browser, so nothing you convert is uploaded anywhere.