JSON-to-CSV is one of the most common data conversions: APIs return JSON, but spreadsheets and BI tools want CSV. The conversion is easy when your JSON is a flat array of objects — and tricky when it isn't. Here are five approaches with their trade-offs.

The easy case: flat array of objects

Most JSON-to-CSV converters expect input in this shape:

[
  {"name": "Alice", "age": 30, "role": "admin"},
  {"name": "Bob",   "age": 25, "role": "user"}
]

The mapping is obvious: each object becomes a row, each key becomes a column header. If your JSON already looks like this, any tool works.

Method 1: online converter

For one-off conversions, our JSON to CSV converter handles the flat case in two clicks and lets you pick the delimiter (comma, tab, semicolon). It also handles arrays of unequal-shaped objects by union-ing the keys.

Method 2: Python with pandas

For programmatic conversion, pandas is the workhorse:

import pandas as pd, json

with open('data.json') as f:
    data = json.load(f)

df = pd.DataFrame(data)
df.to_csv('out.csv', index=False)

If your JSON has nested objects, use json_normalize to flatten them:

df = pd.json_normalize(data, sep='_')
# nested.address.city becomes "address_city"

For arrays nested in records (one record has many tags, say), json_normalize can expand them with the record_path argument — though at some point you're better off thinking about whether one row per record really makes sense.

Method 3: jq for command-line

If you live in the shell, jq converts JSON to CSV in one pipeline:

cat data.json | jq -r '
  (.[0] | keys_unsorted) as $keys |
  $keys, (.[] | [.[$keys[]]])
  | @csv
' > out.csv

What's happening: (.[0] | keys_unsorted) grabs the headers from the first object. The next line emits each row as an array, in header order. @csv handles quoting and escaping properly (quotes inside fields become "", fields with commas get wrapped). This is the fastest method for huge files because jq streams.

Method 4: Node.js with json2csv

npm install @json2csv/plainjs

import { Parser } from '@json2csv/plainjs';
const parser = new Parser({ fields: ['name', 'age', 'role'] });
const csv = parser.parse(data);

Specifying fields explicitly gives you control over column order and which keys are included — useful when the JSON has more keys than you want exported.

Method 5: PowerShell (Windows)

Get-Content data.json | ConvertFrom-Json | Export-Csv out.csv -NoTypeInformation

Built-in, no dependencies. Surprisingly capable for sysadmin scripts.

The hard case: nested data

Real JSON often has nested arrays and objects. There's no canonical way to represent that in CSV — you have to pick a strategy:

Flatten with dot-paths. {"user": {"name": "A"}} becomes a column called user.name. Works when the nesting is shallow and uniform. Breaks for arrays of objects.

One row per leaf. Duplicate parent fields across rows. {"order": "X", "items": [{"sku": "A"}, {"sku": "B"}]} becomes two rows: X, A and X, B. This is what database OLAP tools do.

JSON-in-a-cell. Serialize the nested structure as a JSON string in one cell. Preserves data, but spreadsheets can't query it.

Whichever you pick, document it. The next person looking at the CSV won't be able to reverse-engineer your choice.

CSV quoting rules to know

The CSV spec (RFC 4180) requires: fields containing commas, double-quotes, or line breaks must be enclosed in double quotes; literal double-quotes inside a quoted field are doubled (""). Every tool above handles this. Don't try to write your own CSV serializer with string concatenation — you will get the edge cases wrong.

Wrap-up

For one-time conversions, the online tool is fastest. For automation, pick the tool that matches your stack: pandas for data work, jq for scripts, json2csv for Node services. Reach for explicit flattening rules whenever your JSON has nesting deeper than one level.