BrainCoder
All guides

How to Convert CSV to JSON Online (Without Losing a Column)

BrainCoder5 min read

Convert CSV to JSON in your browser with a real RFC 4180 parser: quoted commas, embedded newlines, doubled quotes, CRLF, CR and LF, a UTF-8 BOM, honest delimiter detection, and every decision the converter made listed on screen.

Why a one-line CSV to JSON converter gets it wrong

The reason people paste CSV into a converter and get back something subtly broken is almost never the JSON side. It is the CSV side. A cell that contains a comma has to be quoted; a quoted cell can contain a line break; a quote inside a quoted cell is written as two quotes; some exporters use semicolons or tabs because the data itself contains commas; some files start with a byte order mark; and Windows tools write CRLF while old Mac tools wrote a bare CR. Split the text on a comma and each of those turns a column into fragments or loses a row entirely.

So the first question when you choose one is not what it outputs but what it does with the awkward cases. This page writes the parser out by hand for exactly that reason, and the test below is whether it tells you what it found.

Paste it, and read the delimiter decision first

Paste the CSV or open a file - there is no sample data loaded on the page, so nothing you see can be confused with your own. Then read the delimiter line before you read anything else, because the wrong delimiter produces output that looks plausible and is completely wrong. Auto-detect scores comma, semicolon, tab and pipe over the first two dozen records and reports its confidence: high means the chosen delimiter appears in every sampled record and no other candidate appears at all, medium means it is the only candidate present but not in every record, and low means another delimiter also appears in the data - which usually means one of them is inside cell text. The header row is rendered above the output, so the fastest check is whether those keys look like your columns.

A file that is semicolon-separated or tab-separated converts the same way once you pick it by hand. Single-column files need no delimiter at all and the page says so rather than pretending to detect something.

What RFC 4180 actually promises, and where this one stops

RFC 4180 is specific: fields separated by commas, records ended by CRLF, optional double quotes around any field, a doubled quote meaning one literal quote, and a line break allowed inside a quoted field. This parser does all of that, and it treats LF and a bare CR as record endings too, which is an extension rather than part of the specification.

There are three more extensions, all disclosed on the page: a leading UTF-8 byte order mark is skipped, a blank line is skipped rather than becoming an empty row, and a trailing line ending does not create an empty record. Each of those is what a spreadsheet does, which is why they are the defaults - but they are choices, and on a single-column file an empty line cannot be told apart from a row holding one empty cell.

One case is refused rather than guessed: a double quote in the middle of a field that was never quoted is not legal CSV, and accepting it quietly is how a delimiter inside a cell gets mistaken for a column break. The text is kept and the position is reported - record, field and character number - so you can go and look at the file rather than wondering what the tool did.

Every value is a string, and that is the point

The most consequential decision on the page is the one it refuses to make. No type is inferred. The string 00123 stays 00123, so a UK postcode, a phone number, a product code and a zero-padded identifier all survive. TRUE stays the five characters TRUE rather than becoming the boolean true. A date written 3/4/26 stays 3/4/26 instead of being rewritten as an ISO date in the wrong order. A number written with a thousands separator stays as it was written rather than becoming a number that means something different.

The only null values in the output are the cells a short row never had, and that is a different thing from an empty cell: an empty cell is something the CSV said, a missing cell is something it did not. If you want numbers, convert them where you consume the JSON, in code, where you can see the rule.

When rows and headers disagree

Real exports are messy, so the two common failures are handled in the open rather than smoothed over. A row with fewer fields than the header has keys gets JSON null in the missing cells, and a row with more fields keeps its extra values in an array under a name you can see in the output rather than dropping them. Both counts are reported, and the first affected row number is given so you can find it in your file.

Duplicate column names are the other one. Two columns called amount cannot both be amount in a JSON object - the second would silently overwrite the first - so the second becomes amount (2), the third amount (3), and if that would collide with a name already in use the counter keeps going. Every rename is listed on the page. The first occurrence always keeps the original name, which keeps the common case working the way your other exports do.

An empty header cell has no name to use, so it becomes columnN for its position. Surrounding whitespace on a header cell is trimmed before it becomes a key; the cell values themselves are never touched.

Caps, previews, and what the page will not do for you

Four caps are checked before any parsing work starts: 5,242,880 characters of pasted text, 5 MB per opened file, 20,000 rows, and 512 columns in a single row, plus 100,000 characters in one cell. Each is refused with its real numbers rather than truncated, because a truncated CSV converts into JSON that is wrong in a way nobody can see. The cell-length cap is the one people hit by accident - a CSV with a whole log file or a base64 blob in one cell.

Both panels on the page are labelled as previews and are deliberately bounded: a data table showing the first twenty rows and eight columns, and a JSON pane showing the first 20,000 characters. Copy and Download give you the complete document, and the byte count on screen is measured on that exact text, so what the number says is what the file contains. Re-parsing the downloaded file gives back the same document.

What it does not do is worth knowing before you rely on it: no Excel serial dates, no locale-aware numbers or currencies, no #N/A or other error values, no stripping of the leading apostrophe that marks a cell as text, no formula evaluation - =SUM(A1:A9) stays that literal string - and no encoding sniffing, so a Windows-1252 export arrives with U+FFFD characters and the page tells you how many it counted. It also does not convert JSON back to CSV; its old reverse mode was removed rather than left half-implemented, because a round trip that changes types on the way out is worse than no round trip.

Privacy

Your CSV is read with the browser's own file API and parsed in the tab. No request is made with your data, and nothing is uploaded - which matters more here than on most pages, because a CSV export is usually customer records, orders or an internal report. Same-origin static assets are all this page loads.

One thing to keep in mind as a general habit rather than a bug in this tool: a CSV cell can contain markup, and this page renders every cell as escaped text, so a cell holding a script tag shows you a script tag. That is the right behaviour, but it means the value of any converter you use - including this one - is exactly the value of its output.

Try it free — CSV to JSON Converter

Convert CSV to JSON with a real RFC 4180 parser: quoted commas, embedded newlines, doubled quotes, CRLF, LF, CR and a UTF-8 BOM. Auto-detects comma, semicolon, tab or pipe and says how sure it is. Every value stays a string.

Open CSV to JSON Converter