← All articles

How to Convert JSON to CSV (and Back)

Convert JSON to CSV and CSV to JSON — in JavaScript, Python, and online. Covers the array-of-objects mapping, quoting rules, nested values, and type coercion.

JSON is the language of APIs; CSV is the language of spreadsheets, databases, and analysts. Converting between them is a daily task — exporting an API response into Excel, or turning a spreadsheet into JSON for an import. This guide shows how to convert JSON to CSV and CSV back to JSON, in JavaScript, in Python, and instantly in your browser — and the edge cases (nested data, quoting, types) that trip people up.

The Core Mapping: Array of Objects ⇄ Rows

A CSV file is a table: one header row of column names, then one row per record. The natural JSON shape that maps onto a table is an array of objects, where each object is a row and each key is a column.

// JSON
[
  { "id": 1, "name": "Ada Lovelace", "active": true },
  { "id": 2, "name": "Bob Khan", "active": false }
]
# CSV
id,name,active
1,Ada Lovelace,true
2,Bob Khan,false

The header is the union of every object's keys (so objects with different fields still line up), and each row pulls the matching value for each column.

How to Convert JSON to CSV in JavaScript

There's no built-in JSON.toCSV, but the conversion is short. The only real work is escaping: any value containing a comma, double quote, or newline must be wrapped in double quotes, and embedded quotes doubled.

function jsonToCsv(rows) {
  if (!rows.length) return '';
  const headers = [...new Set(rows.flatMap(Object.keys))];

  const escape = (v) => {
    if (v == null) return '';
    const s = typeof v === 'object' ? JSON.stringify(v) : String(v);
    return /[",\n\r]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s;
  };

  const lines = [headers.join(',')];
  for (const row of rows) {
    lines.push(headers.map((h) => escape(row[h])).join(','));
  }
  return lines.join('\n');
}

Note the typeof v === 'object' branch: a nested object or array has no flat CSV representation, so the common convention is to serialise it back to JSON text inside the cell. More on that below.

How to Convert CSV to JSON in JavaScript

Going the other way, the trap is parsing CSV correctly — fields can contain commas and newlines inside quotes, so you can't just split(','). Use a small state machine (or a library like papaparse for production):

function csvToJson(text) {
  const rows = [];
  let row = [], field = '', inQuotes = false;
  for (let i = 0; i < text.length; i++) {
    const c = text[i];
    if (inQuotes) {
      if (c === '"' && text[i + 1] === '"') { field += '"'; i++; }
      else if (c === '"') inQuotes = false;
      else field += c;
    } else if (c === '"') inQuotes = true;
    else if (c === ',') { row.push(field); field = ''; }
    else if (c === '\n') { row.push(field); rows.push(row); row = []; field = ''; }
    else if (c !== '\r') field += c;
  }
  if (field || row.length) { row.push(field); rows.push(row); }

  const [headers, ...data] = rows;
  return data.map((cells) =>
    Object.fromEntries(headers.map((h, i) => [h, cells[i] ?? ''])));
}

How to Convert JSON and CSV in Python

Python's standard library has this built in — no dependencies needed.

import csv, json, io

# JSON -> CSV
rows = json.loads(json_text)
buf = io.StringIO()
writer = csv.DictWriter(buf, fieldnames=list(rows[0].keys()))
writer.writeheader()
writer.writerows(rows)
csv_text = buf.getvalue()

# CSV -> JSON
rows = list(csv.DictReader(io.StringIO(csv_text)))
json_text = json.dumps(rows, indent=2)

The Edge Cases That Actually Matter

Nested objects and arrays

CSV is flat; JSON is not. When a value is an object or array, you have two choices: serialise it to JSON inside one cell (simple, reversible) or flatten it into multiple columns like address.city, address.zip (readable, but lossy and harder to reverse). For round-tripping, JSON-in-a-cell is safer.

Types are lost in CSV

CSV has no types — every field is text. Converting CSV → JSON, "1" is a string unless you deliberately coerce it to a number. Be careful with values like 007 (a ZIP/ID that must stay a string) or huge integers that lose precision as numbers. Coerce only when the round-trip is lossless.

Quoting and delimiters

Always quote fields containing commas, quotes, or newlines. Some locales use ; as the delimiter (common in European Excel) — if your CSV looks wrong in one column, check the delimiter before anything else.

Inconsistent keys

If your JSON objects don't all share the same keys, build the header from the union of keys and leave missing cells blank — don't assume the first object defines every column.

Excel and the UTF-8 BOM

If your CSV will be opened in Excel and contains non-ASCII characters, prepend a UTF-8 BOM (the bytes 0xEF 0xBB 0xBF). Excel reads BOM-less UTF-8 as the legacy encoding and mangles accents/Asian characters. Most CSV libraries can emit the BOM via an option.

// JavaScript — write a BOM so Excel reads UTF-8 correctly
const out = '\uFEFF' + jsonToCsv(rows);

Alternative Delimiters (CSV vs TSV vs ;)

"CSV" isn't always comma-separated. Common variants:

  • TSV — tab-separated; safer when values often contain commas.
  • European Excel emits ; as the delimiter on locales where the decimal mark is a comma.

If your output looks like a single weird column when opened, the file uses a different delimiter than the reader expects. Standardise on one (CSV with , + BOM for cross-locale Excel, or TSV for engineering pipelines).

For real-world CSV use PapaParse

For browser/Node parsing of CSV that arrives from users, use PapaParse — it handles delimiter detection, quoted fields, multi-line values, header rows, and dynamicTyping for number/boolean coercion. The hand-rolled snippets above are fine for trusted, simple inputs; PapaParse is what to reach for at scale.

Convert JSON to CSV Online — No Setup

For a one-off conversion, skip the code entirely. Paste your JSON into fixjson's JSON to CSV converter and click To CSV, or paste CSV and click To JSON. It handles the quoting, the key union, and type coercion automatically, and runs entirely in your browser — nothing is uploaded, which matters when the data contains customer records or internal exports.

Frequently Asked Questions

How do I convert JSON to CSV?

Take a JSON array of objects, build a header row from the union of all keys, then write one row per object — quoting any value that contains a comma, quote, or newline. Use csv.DictWriter in Python, a small function in JavaScript, or paste it into the online converter.

How do I convert CSV to JSON?

Parse the CSV (respecting quoted fields), treat the first row as the header, and map each following row to an object keyed by those headers. Remember that all values arrive as strings unless you coerce them.

How are nested JSON objects represented in CSV?

CSV can't nest, so a nested object or array is usually written as JSON text inside a single cell, or flattened into dotted columns like address.city. JSON-in-a-cell is the reversible option.

Can I convert JSON to CSV online for free?

Yes — fixjson's converter does both directions for free, entirely in your browser, with no account and no upload.

Related Tools & Guides