How to Convert JSON to CSV in JavaScript and Python
Joining values with commas breaks on the first name that contains one. Here is a short, tested JSON to CSV converter for JavaScript and Python, and the details that make Excel open it correctly.
To convert JSON to CSV in code, you need correct quoting and a complete header row. The JSON to CSV Converter handles a one-off export in the browser, and its page explains how nested data is squeezed into columns. When the export runs on a schedule or behind a Download button, you need the same conversion in code, and the usual first attempt, joining values with commas, produces a broken file.
This guide gives a tested converter for each language and the details that decide whether the file opens correctly.
Convert JSON to CSV in JavaScript
const csvField = (value) => {
const text = value === undefined || value === null ? "" : String(value);
return /[",\n\r]/.test(text) ? '"' + text.replaceAll('"', '""') + '"' : text;
};
function toCsv(rows) {
const headers = [...new Set(rows.flatMap((row) => Object.keys(row)))];
const lines = [headers, ...rows.map((row) => headers.map((h) => row[h]))];
return lines.map((line) => line.map(csvField).join(",")).join("\r\n") + "\r\n";
}toCsv(records)
Input
[
{ "id": "ord_1", "customer": "O'Brien, Ana", "note": "said \"fragile\"", "total": 120.5 },
{ "id": "ord_2", "customer": "José", "total": 35, "gift": true }
]Output
id,customer,note,total,gift
ord_1,"O'Brien, Ana","said ""fragile""",120.5,
ord_2,José,,35,trueThree details make this correct. The header is the union of the keys in every record, so gift, which only the second order has, still gets a column. A field containing a comma, a quote or a line break is wrapped in double quotes, with each quote inside doubled, as RFC 4180 describes. And rows end with \r\n, the line ending that standard specifies.
Convert JSON to CSV in Python
import csv
def write_csv(records, path):
fields = list(dict.fromkeys(key for record in records for key in record))
with open(path, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=fields, restval="")
writer.writeheader()
writer.writerows(records)dict.fromkeys collects every key once in first-seen order, and restval="" fills the cells a record does not have. The csv module does the quoting. Open the file with newline="", as the csv documentation asks; without it, Windows writes an extra line break and every row is followed by a blank line. One small difference from the JavaScript version: Python writes the boolean True where JavaScript writes true.
Nested values
Both converters expect flat records. A nested object such as customer: { name, country } would come out as [object Object] in JavaScript and as a Python dict representation in Python. Flatten each record first, so customer.name and customer.country become their own columns; the JSON Flattener guide has a function for that. For arrays that should stay together, such as a list of tags, write them as one JSON string per cell with JSON.stringify or json.dumps.
Making the file open cleanly in Excel
- Accents and other non-ASCII text. Excel does not always detect UTF-8 when a CSV file is opened by double-clicking it. Starting the file with a byte order mark, the character
\uFEFF, makes it read the file as UTF-8. Write it in Python withencoding="utf-8-sig", or prepend it to the string in JavaScript. - Long numbers and leading zeros. Excel shows numbers with at most 15 significant digits and drops leading zeros, so an 18-digit order ID or a postcode such as
007changes when the file is opened. The data in the file is correct; the display is not. Users who need those columns should import the file and mark the columns as text. - Formula injection. A cell that begins with
=,+,-or@can be treated as a formula when the file is opened in a spreadsheet. If any column contains text typed by users, such as names or comments, prefix such values with a single quote or a space before writing them.
Related tools
Parse CSV into a clean array of typed JSON objects, header-aware.
Flatten nested JSON into single-level dot-notation key paths.
Turn JSON into clean, readable YAML for configs, pipelines and manifests.
Pretty-print JSON with configurable indentation and instant validation.
Related guides
A single quoted comma breaks the split approach. Here is correct CSV parsing in Python and JavaScript, the byte order mark that renames your first column, and safe type conversion.
A recursive function of about ten lines flattens any JSON document into path keys. Here it is for JavaScript and Python, with the choices that decide whether you can rebuild the original.
YAML is easier to read and easier to get wrong. Here is what each format gives you for configuration, the mistakes YAML lets through, and a rule for choosing.
Two formatters can disagree about the same JSON file. Here is how a team picks one, applies it in every editor and before every commit, and makes CI enforce it.