How to Convert CSV to JSON in JavaScript and Python
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.
To convert CSV to JSON in code, you need a real CSV parser, not split(","). The CSV to JSON Converter turns a spreadsheet export into JSON in the browser, and its page explains why CSV is really a family of formats. In code, the tempting shortcut is to split each line on newlines and then on commas. It works on the first test file and fails on the first real one.
This guide shows why, how to parse CSV correctly in Python and JavaScript, and how to turn the resulting strings into the right types.
Why split fails
id,customer,note
ord_1,"O'Brien, Ana","said ""fragile""
on two lines"
ord_2,José,This is valid CSV. The customer name contains a comma, so it is quoted. The note contains quotes, written as doubled quotes, and a line break, which is allowed inside a quoted field. Splitting the second line on commas gives four broken pieces, including "O'Brien and Ana", and splitting the file on newlines first cuts the note in half.
Convert CSV to JSON in Python
import csv
import json
with open("orders.csv", newline="", encoding="utf-8-sig") as f:
rows = list(csv.DictReader(f))
print(json.dumps(rows, ensure_ascii=False, indent=2))DictReader uses the first row as keys and handles quoting and line breaks inside fields. The utf-8-sig encoding removes a byte order mark if the file has one. With plain utf-8, a file saved from Excel produced the first key \ufeffid instead of id, so row["id"] raised a KeyError even though the column was clearly there.
Convert CSV to JSON in JavaScript
JavaScript has no built-in CSV parser. For large or untrusted files, use a maintained library. For known input, this function handles quoted fields, doubled quotes and line breaks inside quotes:
function parseCsv(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" || c === "\r") {
if (c === "\r" && text[i + 1] === "\n") i++;
row.push(field); rows.push(row); row = []; field = "";
} else field += c;
}
if (field !== "" || row.length > 0) { row.push(field); rows.push(row); }
return rows;
}
const [header, ...data] = parseCsv(text.replace(/^\uFEFF/, ""));
const records = data.map((cells) => Object.fromEntries(header.map((h, i) => [h, cells[i]])));On the file above it returns three rows, with O'Brien, Ana as one field and the note intact, line break included. The replace removes a byte order mark, the same job utf-8-sig does in Python.
Converting types without losing data
Every value comes out of a CSV file as a string. Converting everything that looks numeric is the next trap:
Number("007") // 7 the leading zeros are gone
Number("") // 0 an empty cell becomes zero
Number("1e3") // 1000
Number("12345678901234567890") // 12345678901234567000Postcodes, phone numbers, IDs and anything else with leading zeros or more than 15 digits must stay strings. An empty cell usually means missing, which Number turns into a real zero. Convert per column, using a list of the columns you know are numeric, and turn empty strings into null rather than 0.
Related tools
Flatten an array of JSON objects into spreadsheet-ready CSV.
Pretty-print JSON with configurable indentation and instant validation.
Parse any YAML config into strict, valid JSON your code can consume.
Validate JSON syntax and pinpoint the exact line and column of any error.
Related guides
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.
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.
Two lines of code convert YAML to JSON, and the parser's defaults decide whether merge keys apply, dates stay strings and no means false. Here are the options that matter, tested.
The same file opens cleanly in VS Code and is rejected by npm. The difference is which of three JSON dialects each tool reads.