JSON to CSV Conversion — Complete Guide
What Is JSON to CSV Conversion?
JSON and CSV are two of the most common data formats in development, but they model data very differently. JSON is a tree: objects nest inside objects, and arrays can hold any shape. CSV is a grid: a flat table of rows and columns where every row has the same fields. Converting JSON to CSV means taking a nested document and projecting it onto that flat grid — a task you'll face constantly when APIs hand you JSON but your spreadsheet, BI tool, or legacy pipeline expects CSV.
Why Convert JSON to CSV at All?
The practical reasons are everywhere:
- Excel and Google Sheets import — CSV opens natively in spreadsheets; JSON does not.
- Data analysis — pandas, R, and most analytics tooling read CSVs with one function call.
- ETL and reporting — legacy systems and scheduled jobs often accept only delimited files.
- Sharing with non-developers — a CSV can be reviewed by anyone with a spreadsheet app.
The good news: you don't need to write the transformation by hand. Our free JSON to CSV Converter handles nested objects and arrays in one paste — but understanding what it does under the hood will save you from subtle data-loss bugs.
Flattening Nested Objects
CSV has no concept of nesting, so nested objects are flattened into dotted or underscored column names. Take this order document:
{
"order": 1001,
"customer": { "name": "Ada Lovelace", "email": "ada@example.com" },
"total": 249.99
}
Flattened to CSV, it becomes:
order,customer.name,customer.email,total
1001,Ada Lovelace,ada@example.com,249.99
Note the convention: customer.name uses a dot to show the original path. As long as you flatten consistently, the data is fully recoverable — you can rebuild the original object by splitting on the dots.
Arrays: Rows vs Cells
Arrays are where the design decisions happen. You have two main strategies:
- Expand (normalize) — each array element becomes its own row, duplicating the parent fields. This is the right choice for line items, events, or anything you want to aggregate in a pivot table.
- Embed — serialize the array as a JSON string inside a single cell. This preserves the structure exactly but makes the column useless for filtering and math.
Neither is "wrong" — pick based on what your consumer will do with the data. Good converters (ours included) let you toggle between the two.
When Conversion Is Lossy
JSON to CSV is not always lossless. Watch out for these traps:
- Mixed-type arrays —
[1, "two", null]has no clean column type; the CSV will hold whatever string form each value takes. - Heterogeneous objects — if two rows have different keys, missing fields become empty cells, and you can't tell an explicit
nullfrom an absent key. - Type information — CSV is text. A number
1001may come back as a string depending on the spreadsheet's import settings. - Deep nesting — objects nested three or four levels deep produce long, unwieldy column names and are easy to get wrong by hand.
None of this means you should avoid the conversion — just validate your output before relying on it.
Converting with JavaScript
A minimal flatten-and-serialize pipeline in JavaScript looks like this:
const flatten = (obj, prefix = '') =>
Object.entries(obj).flatMap(([k, v]) =>
v !== null && typeof v === 'object' && !Array.isArray(v)
? flatten(v, `${prefix}${k}.`)
: [[`${prefix}${k}`, v]]
);
const order = { order: 1001, customer: { name: 'Ada', email: 'ada@example.com' } };
const row = Object.fromEntries(flatten(order));
// { order: 1001, 'customer.name': 'Ada', 'customer.email': 'ada@example.com' }
console.log(Object.keys(row).join(','));
console.log(Object.values(row).join(','));
This recursive flatten handles any depth, and the resulting array of row objects is exactly what libraries like csv-stringify expect.
Converting with Python
Python's standard library makes the same job straightforward:
import csv, json
orders = json.loads('[{"order":1001,"customer":{"name":"Ada"}},{"order":1002,"customer":{"name":"Grace"}}]')
rows = [{"order": o["order"], "customer.name": o["customer"]["name"]} for o in orders]
with open("orders.csv", "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=rows[0].keys())
writer.writeheader()
writer.writerows(rows)
For deeply nested data, the pandas.json_normalize() function does the recursive flattening for you in one line.
Try It Live
Skip the boilerplate — paste your JSON into our JSON to CSV Converter and get clean, properly quoted CSV back instantly. It handles nested objects, arrays-as-rows, and quotes/escapes every field correctly.
FAQ
Is JSON to CSV conversion lossless?
Not always. Nested structures can be flattened and rebuilt, but mixed-type arrays, heterogeneous keys, and type information (numbers vs strings) can be lost. Always spot-check the output.
How do I handle arrays of objects in CSV?
Either expand each object into its own row (duplicating parent fields) or embed the array as a JSON string in a single cell. Choose expand when you need to aggregate or filter; embed when fidelity matters more.
Why do my CSV values contain commas and quotes?
CSV escapes fields containing commas, quotes, or newlines by wrapping them in double quotes and doubling any internal quotes. That's correct behavior — spreadsheet apps handle it transparently.