Guides · Data
CSV to JSON: A Developer's Quick Reference
What actually happens converting tabular CSV data into nested JSON, and the edge cases that trip up a naive converter.
CSV and JSON represent the same underlying data very differently — one is flat and row-based, the other is nested and key-based — which means "convert CSV to JSON" involves real decisions, not just a format swap. Here's what's actually happening, and where it tends to go wrong.
The basic mapping
A CSV file's first row is normally treated as column headers, and every row after that becomes one JSON object, with each column header becoming a key and that row's value in that column becoming the value — the whole file becomes an array of objects, one per row. This is the default and the right choice for the overwhelming majority of CSV files: exported spreadsheet data, a database table dump, a contact list.
Type inference — the part that causes the most surprises
CSV has no concept of data types at all — every single value in a CSV file is just text, including things that are obviously numbers, booleans, or dates to a human reading them. JSON does have real types (numbers, booleans, null, strings), so a converter has to decide whether "42" should become the number 42 or stay the string "42", whether "true" should become the boolean true or the string "true," and so on. Getting this right matters a lot if the JSON is headed into code that expects real numbers to do math on, or real booleans to branch on — a value silently staying a string when downstream code expects a number is a classic, quietly-broken-until-it-isn't bug.
Leading zeros: the type-inference trap
This deserves calling out specifically because it breaks real data constantly: a ZIP code like "00501," an account number, or an ID field that happens to start with a zero looks like a number to a naive type-inference rule, but converting it to the actual number 501 silently destroys the leading zeros — and there's no way to recover them afterward, since 501 and 00501 are the same number. Good practice here treats a purely numeric-looking string as a number only when it doesn't start with a leading zero (aside from "0" itself), and otherwise preserves it as a string exactly as written — better to keep something as text that could have safely been a number than to mangle an identifier that can't.
Missing values, empty cells, and inconsistent rows
Real-world CSV exports are rarely perfectly rectangular — a trailing comma leaves an empty final column, a row has fewer commas than the header row implies, or a cell is legitimately blank versus containing the literal word "null." A reasonable converter needs a consistent rule for what an empty CSV cell becomes in JSON (usually an empty string, sometimes null depending on convention) and needs to handle a row with fewer fields than the header without silently misaligning every subsequent key — a shifted-by-one-column row is a much worse failure than a missing field, because it's wrong in a way that isn't obviously wrong.
Quoted fields containing commas or newlines
The CSV format allows a field's actual value to contain a comma, or even a line break, as long as the whole field is wrapped in quotes — "Smith, John" as a single value in a two-column file, for instance. A converter that just splits on every comma without respecting quotes will shred a value like that into extra columns that don't belong. This is a well-understood edge case in CSV parsing generally (not specific to CSV-to-JSON), but it's exactly the kind of thing that looks fine on a simple test file and breaks the first time it meets a real export from someone else's system.
Going back the other way
The reverse conversion — JSON back to CSV — has the opposite problem: JSON allows nested objects and arrays inside a single record, which have no natural row-and-column representation. Flattening nested JSON into CSV always involves a real decision about how to represent that nesting (dotted key names, repeated rows, or dropping nested detail entirely), which is worth being aware of if a round-trip through both formats is part of a pipeline — CSV to JSON and back to CSV isn't guaranteed to reproduce the original file byte-for-byte, even when no data is technically lost.
