JSON to CSV Converter — Free Online JSON to CSV Tool

Convert JSON arrays into CSV format instantly. Flatten nested objects with dot notation, handle complex structures, and download the result as a .csv file. 100% client-side — your data stays private.

JSON to CSV Converter

JSON Input
CSV Output Ready

How do you convert JSON to CSV? You turn a JSON array of objects into a table by making each object a row and each key a column, then flattening any nested object into a dotted column name — {"address":{"city":"NYC"}} becomes a column called address.city. The header row is the union of every key seen across all objects, so rows with different shapes still line up, and any key an object is missing produces an empty cell.

How to Use the JSON to CSV Converter

  1. Paste a JSON array into the left panel — The top level must be an array — [ { … }, { … } ]. A single object, an object wrapping an array under a data key, or newline-delimited JSON will be rejected with a message saying so. Use Load Sample to see the expected shape.
  2. Click Convert — The tool parses the JSON, flattens each object and builds the CSV. The tag above the output panel shows the row count on success and turns red with the parse error on failure — the message comes from JSON.parse, so it names the character position where the syntax broke.
  3. Check how nested data came out — Nested objects become dotted columns to any depth. Arrays are not expanded into columns — each one is written into a single cell as its JSON text, so ["reading","gaming"] appears as one quoted value rather than two fields.
  4. Confirm the header row — Headers are collected from every row in first-seen order, not just from the first object. If a key appears only in row 50 it still gets a column, and every earlier row gets an empty cell for it — worth scanning before you import.
  5. Copy or download the resultCopy puts the CSV on your clipboard for pasting straight into a sheet. Download CSV saves it as data.csv with a UTF-8 blob; rename it afterwards if you are keeping several exports.

How the Conversion Works

CSV is a flat, rectangular format and JSON is a tree, so every JSON-to-CSV converter has to answer the same question: what happens to the parts of the tree that do not fit in a grid. This one makes three specific choices, and knowing them tells you exactly what to expect from your data.

1. Objects flatten, arrays do not

Each row is walked recursively. Whenever a value is a plain object, its keys are hoisted into the parent with a dotted prefix, repeatedly, until only scalars remain — user.address.geo.lat is a perfectly ordinary column name here. Whenever a value is an array, the recursion stops and the array is serialised with JSON.stringify into a single cell. That keeps the data lossless but not analysable: you can read the array back out later, but you cannot sort or filter on its elements in a spreadsheet.

2. Headers are the union of all keys

After every row is flattened, the tool walks all of them and collects each column name the first time it appears. The practical effect is that ragged data still converts cleanly — an API that omits null fields, or a log export where later records gained a new attribute, produces one column per distinct key with blanks where a record had nothing. The order of the columns is the order the keys were first encountered, so the first record's shape usually determines the left-hand side of the sheet.

3. Quoting follows RFC 4180

A cell is wrapped in double quotes only when it needs to be — when the value contains a comma, a double quote or a newline — and any double quote inside is doubled. That is the escaping rule every spreadsheet and CSV library expects:

He said "hi", loudly → "He said ""hi"", loudly"

The delimiter is always a comma and rows are separated by a single line feed. Values are converted with JavaScript's default string conversion, so true and false become the words, and null and missing keys both become an empty cell — the CSV cannot distinguish an explicit null from an absent field.

Example: Nested JSON to Flat CSV

This is the sample the Load Sample button inserts, with an object and an array of strings per record:

[
  {"name": "Alice", "age": 30, "address": {"city": "New York", "zip": "10001"}, "hobbies": ["reading", "gaming"]},
  {"name": "Bob", "age": 25, "address": {"city": "Los Angeles", "zip": "90001"}, "hobbies": ["hiking"]}
]

Produces:

name,age,address.city,address.zip,hobbies
Alice,30,New York,10001,"[""reading"",""gaming""]"
Bob,25,Los Angeles,90001,"[""hiking""]"

Note what happened to hobbies. The array became JSON text, that text contains commas and quotes, so the whole cell was quoted and its internal quotes doubled. A spreadsheet will show it as ["reading","gaming"] in one cell. If you need one hobby per column or one row per hobby, reshape the JSON before converting — no flattening rule can decide that for you.

Getting Clean Results in a Spreadsheet

Most surprises after a JSON-to-CSV conversion come from the spreadsheet, not the conversion. CSV has no type system: every cell is text, and the application guesses what it means on import. Those guesses are where identifiers get mangled.

  • Leading zeros disappear. A zip code of 01234 or a part number of 007 becomes a number on import. Import the file through your spreadsheet's text-import dialog and mark those columns as text rather than double-clicking the file.
  • Long numbers lose precision twice. JSON integers beyond about 9 quadrillion already lose accuracy in JSON.parse, and spreadsheets round to 15 significant digits on top of that. Snowflake IDs and large account numbers should be strings in the JSON before you start.
  • Date-like strings get reformatted. A value such as 2024-03-05 may be re-rendered in the locale's date format the moment it is imported. Again, import as text if the exact string matters.
  • Accented characters can render as mojibake in Excel. The download is UTF-8 without a byte-order mark, and Excel on Windows historically assumes the system code page for a double-clicked .csv. Use Data → From Text/CSV and pick UTF-8, or open the file in Google Sheets, which reads UTF-8 by default.
  • Very deep nesting makes unwieldy headers. Four levels produce names like a.b.c.d. That is valid, but some import tools treat dots as path separators — rename the columns after import if your destination does.

Frequently Asked Questions

The top level has to be an array: [{"key": "value"}, …]. Each element becomes one row. A bare object, an empty array, and newline-delimited JSON are all rejected with an explicit message. If your API wraps the records — {"data": [...]} is the common pattern — paste just the inner array. Elements that are not objects still convert, landing in a single column named value.

Nested objects are flattened to any depth with dots, so {"address":{"geo":{"lat":1}}} becomes the column address.geo.lat. Arrays are not expanded — each array is written into one cell as its JSON text, which keeps the data but makes it unsortable in a spreadsheet. If you need one row per array element, reshape the JSON first; no automatic rule can decide whether an array should become columns or rows.

None of them individually — the headers are the union of every key across every row, recorded in the order each key is first seen. A field that only appears in the last record still gets a column, and every row without it gets an empty cell. This is what lets ragged data from an API that omits null fields convert without losing anything.

That happens on import, not during conversion — the CSV contains 01234 as text, and the spreadsheet reads it as the number 1234. CSV carries no type information, so the application guesses. Use your spreadsheet's text-import path (Data → From Text/CSV in Excel) and set the column type to Text, rather than double-clicking the file. The same guessing turns date-like strings into dates and long identifiers into rounded floats.

Yes in the file, but Excel on Windows may not display them. The download is a UTF-8 blob with no byte-order mark, and a double-clicked .csv is historically read using the system code page there, which turns é into two garbled characters. Import through Data → From Text/CSV and select UTF-8, or open it in Google Sheets or LibreOffice, both of which assume UTF-8.

Not in this tool — the delimiter is a fixed comma and the quoting rule follows RFC 4180, which is what CSV libraries and spreadsheet importers expect. If your locale's Excel expects semicolons, use the text-import dialog and tell it the file is comma-separated rather than converting the file itself. Doing a blind find-and-replace of commas will corrupt every quoted cell that legitimately contains one.

There is no hard limit; parsing and conversion are one synchronous pass in your tab, so tens of thousands of rows are fine and hundreds of thousands will make the page hang while it works. Nothing is sent to a server. Do note that clicking Convert also writes the input JSON into the page URL as a query parameter so a conversion can be bookmarked — clear the panel before sharing that address if the data is customer data.

Because CSV has no way to distinguish them. A JSON null and a key that was simply absent from an object both come out as an empty cell, and so does an empty string. If that distinction matters downstream — an update payload where null means "clear this field" and missing means "leave it alone" — CSV is the wrong intermediate format, and you should keep the data in JSON or convert to a format with a null marker.

Use Cases

Handing an API Response to a Colleague

Someone in finance or operations needs the numbers from an endpoint but not the tooling. Paste the response, convert, download, and send a spreadsheet they can open — no screenshots, no manual retyping.

Eyeballing a MongoDB Export

A collection dumped as a JSON array is hard to scan in a text editor. Flattening it to columns makes gaps obvious immediately — a field present in only half the documents shows up as a half-empty column.

Building a Bulk-Import File

Most CRM, e-commerce and mailing platforms accept CSV uploads and nothing else. Convert the JSON you already have, then rename the columns to whatever the destination's import template expects.

Auditing Field Coverage

Convert a sample of records and look at the header row. Every distinct key across the whole sample gets a column, which turns "which fields does this endpoint actually return?" into something you can answer by scrolling.

Charting Log or Metrics Data

Structured log lines collected as a JSON array become a table you can pivot or plot. Pair it with the Chart from CSV tool to go from raw records to a graph without leaving the browser.

Preparing Test Fixtures for Review

A fixture file with fifty near-identical objects is tedious to check by eye. As a grid, a wrong value in one row stands out against the column, and you can diff two exports as text afterwards.