Convert JSON to CSV
Nested objects become dot-notation columns. You decide what happens to the arrays — before anything is downloaded.
Runs in your browser0 bytes uploadedNested objects become dot-notation columns. You decide what happens to the arrays — before anything is downloaded.
Runs in your browser0 bytes uploadedNothing at the counter yet. Paste JSON, or drop a .json file anywhere on the panel to the left. The column names appear before anything is converted.
A CSV file is a grid: every row has the same columns, and every cell holds one value. JSON is a tree. Values contain objects, objects contain arrays, arrays contain more objects, and nothing forces two records to have the same shape. Converting the second into the first is not a translation — it is a flattening, and a flattening always makes decisions on your behalf.
Most converters make those decisions silently. You paste a document, a file appears, and the fact that a column was dropped or an array was collapsed into a string is something you discover two days later in a spreadsheet. This tool takes the opposite approach: it shows you the column names it is about to produce, tells you what it did to every nested object and every array, and lets you change the strategy before anything is downloaded.
The uncontroversial part. An object inside an object becomes one column per leaf, with the path written out: {"user": {"address": {"city": "Austin"}}}becomes a column named user.address.city. The convention comes from pandas, jq and most data warehouses, so a file produced this way will look familiar to whoever receives it.
There is one caveat worth knowing before you load the result somewhere. Several SQL dialects — BigQuery in particular — reject or mangle a column name containing a dot, because the dot already means "field of a struct". If the CSV is headed for a database loader rather than a spreadsheet, switch the separator to an underscore and you getuser_address_city instead. It is one click, and it saves an import error that is genuinely annoying to diagnose from the other end.
An array inside a record has no single correct representation in a grid, which is exactly why converters differ so much. There are three reasonable answers, and which one is right depends entirely on what the array means.
Join it into one cell. ["red", "blue"] becomesred; blue. This is right for tags, categories, labels — anything where the list is a property of the record rather than a set of related records. It is compact and it keeps one row per record. The cost is that the values are now a string: splitting them apart again is only reliable if no value contains your separator, which is why the default here is a semicolon rather than a comma, and why the separator is a free text field rather than a fixed choice.
Number the columns. tags.0, tags.1,tags.2. This is right when the array has a fixed and small length and position carries meaning — coordinates, a fixed set of scores, the three most recent events. The widest record decides how many columns exist, so a document where one record has forty items and the rest have two produces thirty-eight mostly empty columns. The column preview makes that visible immediately.
One row per item. The record is repeated once for every element, with the surrounding fields duplicated on each row. This is denormalization, and it is what you want for order lines, comments, transactions — arrays whose elements are themselves records. It is also the only one of the three that lets a spreadsheet pivot or a database group over the array contents.
Denormalization has one sharp edge and the tool states it rather than hiding it: two arrays in the same record multiply. A record with three tags and four line items produces twelve rows, not seven, because there is no other mathematically consistent answer. When that is not what you meant, pick a single array to expand and let the others join into cells instead.
One more case is decided for you, because only one answer is defensible. An array that contains objects cannot be joined into a cell without destroying the objects, so it falls back to numbered columns — and says so on the receipt instead of writing[object Object] into your data, which is a genuinely common outcome elsewhere.
Real JSON is ragged. An API omits null fields, a newer record has a field the older ones lack, an optional block appears in one entry out of five hundred. A converter that builds its header from the first record silently drops every field that appears later — the most damaging bug in this category, because the output looks perfectly fine.
Every key found anywhere in the document becomes a column here. Records that lack it get an empty cell, never the string undefined and never the wordnull unless you ask for it. The column preview shows a count such as3/500 on any column that is not present in every row, so a rare field is something you notice before you build a report on it.
CSV has no type system, so every value ends up as text and the receiving program guesses. Three of those guesses are worth controlling.
null becomes an empty cell by default, which is what most spreadsheets and loaders expect. If your destination distinguishes "no value" from "empty string", you can write it out as null or NULL instead. Booleans keep the form JSON gave them — true and false, lowercase, not Excel'sTRUE. Numbers are copied digit for digit from your source rather than being run through JavaScript, which matters more than it sounds: a nineteen-digit Snowflake or Twitter ID does not survive JSON.parse intact, and12345678901234567890 comes back as 12345678901234567000 in every converter that takes the obvious route. Here the digits you pasted are the digits you get.
The delimiter is not universal. Swedish, German, French and most other European Excel installations expect a semicolon, because the comma is the decimal separator in those locales. A comma-separated file opened there lands entirely in column A. If the file is for a colleague rather than a program, ask which one they need — theguide to the CSV format covers why the format has no real standard to appeal to.
The byte order mark is the other half of the same problem. It is three invisible bytes at the start of the file that tell Excel the text is UTF-8. Without it, Excel on Windows falls back to a legacy code page and Malmö arrives asMalmö. Adding it costs nothing for spreadsheets and can confuse a strict parser expecting the first character to be data, so it is a checkbox rather than a default you cannot see. It is written into the downloaded file only, never into what you copy. The difference between the two is exactly whatCSV UTF-8 versus plain CSV means in Excel's own save dialog.
The JSON people convert is usually an export: customer records, order history, a webhook payload, a user table dumped from an internal admin. All of it is parsed and flattened by JavaScript running in this page, and there is no upload endpoint to send it to. Open your browser's network panel and paste a document — no request appears, because there is nowhere for one to go. If the output looks wrong before you convert, the JSON formatter points at the exact line, and theCSV viewer opens the result as a real table afterwards.
They are flattened with dot notation: {"user": {"address": {"city": "Austin"}}} becomes a column called user.address.city. Every level of nesting adds one segment, and the tool lists the column names before you convert anything so you can see exactly what you are about to get. If your target system dislikes dots in column names — BigQuery and most SQL loaders do — you can switch the separator to an underscore.
You pick, because all three answers are correct in different situations. Joining puts every item in one cell separated by a semicolon, which suits tags and categories. Numbered columns give you tags.0, tags.1 and so on, which suits fixed-length data. One row per item duplicates the surrounding fields onto a row for each element, which is what you want for order lines or comments. Arrays that contain objects cannot be joined into a cell without destroying them, so those fall back to numbered columns and the tool tells you it did.
That is normal in JSON and it is the hardest part of writing a correct CSV. Every key found anywhere in the document becomes a column — the union, not the first record — and records that lack that key get an empty cell rather than the word undefined. The column preview marks how many records actually contain each column, so a field present in 3 of 500 records is visible before you open the file in a spreadsheet.