How JSON to CSV conversion works
CSV is a flat, two-dimensional table: rows and columns. The cleanest JSON input is therefore an array of similar objects — each object becomes one row, and each key becomes a column. A 100-object array with 5 keys produces a 100-row, 5-column CSV.
[
{ "id": 1, "name": "Alice", "email": "alice@example.com", "active": true },
{ "id": 2, "name": "Bob", "email": "bob@example.com", "active": false }
]id,name,email,active
1,Alice,alice@example.com,true
2,Bob,bob@example.com,falseHeaders come from the union of all keys
Column headers should be the union of keys across every object, not just the first. If a later object has an extra key, scanning only the first row truncates it. Objects missing a key get an empty cell.
[
{ "id": 1, "name": "Alice" },
{ "id": 2, "name": "Bob", "team": "Support" }
]
// headers: id,name,teamFlatten nested objects with dot notation
CSV cannot store nested objects, so a field like {"address": {"city": "Paris"}} is flattened to a dotted column header address.city. Arrays of primitives are usually joined into one cell with a delimiter; arrays of objects fit CSV poorly and may be better kept as JSON.
[
{ "id": 1, "name": "Alice", "address": { "city": "Paris", "country": "FR" } }
]
// id,name,address.city,address.country
// 1,Alice,Paris,FREscaping commas, quotes, and newlines (RFC 4180)
Any value containing a comma, double quote, or line break is wrapped in double quotes, and inner double quotes are escaped by doubling them. This is what keeps the file parseable in Excel and Google Sheets.
[
{ "note": "Hello, world" },
{ "note": "She said \"yes\"" }
]
// note
// "Hello, world"
// "She said ""yes"""Convert JSON to CSV in code
When you need conversion in a script or pipeline instead of the browser tool:
# jq (command line) — fast, no install beyond jq
jq -r '(.[0] | keys_unsorted) as $k | $k, (.[] | [.[$k[]]] | @csv)' data.json# Python — standard library, handles escaping for you
import json, csv, sys
rows = json.load(open("data.json"))
w = csv.DictWriter(sys.stdout, fieldnames=list(rows[0].keys()))
w.writeheader(); w.writerows(rows)// Node.js — streaming for large files
import { parse } from 'json2csv'
console.log(parse(require('./data.json')))Common JSON to CSV mistakes
- Trying to convert one deeply nested object without first deciding what a "row" is.
- Building headers from only the first object when later rows carry extra keys.
- Flattening arrays into ambiguous text with no delimiter convention.
- Letting spreadsheet apps reinterpret IDs, long numbers, and dates — keep them as text on import.
For a step-by-step walkthrough with more examples, see the JSON to CSV tutorial. To go the other way, use CSV to JSON.