How to use
- Drop your file(s) into the box above — or click it to browse.
- Conversion starts immediately — no settings needed.
- Click Download on each finished file — or Download all (.zip) for a batch. Nothing was uploaded at any point.
What shapes of JSON convert?
The canonical input is an array of objects — what nearly every API returns. Each object becomes a row; the column set is the union of all keys in order of first appearance, so records with missing fields still line up correctly. Three other shapes are handled sensibly: a single object becomes a one-row CSV, an array of arrays converts as raw rows, and an object-of-objects (keyed records) becomes rows with a _key column.
Nested values don't flatten silently: an embedded object or array is written into its cell as compact JSON, so no data is lost — you can always see exactly what was nested where.
| JSON input | CSV output |
|---|---|
| [{"a":1},{"a":2,"b":3}] | Columns a,b — union of keys, blanks for missing |
| {"x":1,"y":2} | One data row |
| {"kim":{"age":3},"lee":{"age":9}} | Rows with a _key column (kim, lee) |
| [[1,2],[3,4]] | Raw rows, no header |
| Nested object in a field | Cell contains compact JSON of it |
The Excel details that actually matter
Two invisible bytes decide whether your CSV opens correctly. First, Excel assumes a legacy encoding unless the file starts with a UTF-8 BOM — without it, Korean, Japanese and accented text turn to garbage. Second, the CSV RFC specifies CRLF line endings, which is also what Excel is happiest with. This converter emits both, plus RFC 4180 quoting for any cell containing commas, quotes or line breaks.
When NOT to convert JSON to CSV
- Deeply nested structures — CSV is a flat table; heavy nesting arrives as JSON-in-cells, which spreadsheets can display but not compute on. Restructure first if you need columns.
- Data returning to an API — round-tripping through CSV loses type fidelity (everything becomes text in Excel). Keep JSON as the source of truth.
- Streaming/huge exports — beyond a few hundred MB, browser memory becomes the limit; use
jqor a script instead.