creatorvalet

Convert CSV to JSON

Every column keeps one type, and you can see which one before you download. Leading zeros and long IDs survive.

Runs in your browser 0 bytes uploaded
Waiting
Rows
Columns
Separator
Encoding
already text
Shape
Indent
Empty cell
№ 9420waiting

Nothing at the counter yet. Paste rows, or drop a .csv file anywhere on the panel to the left. The keys and their types appear before anything is converted.

A cell has no type. A JSON value has five.

Everything in a spreadsheet export is characters. The row 01234,41,TRUE, holds four cells and not one of them announces what it is supposed to be. JSON, on the other end, insists: a value is a string, a number, a boolean, null, or a nested structure, and the choice is written into the punctuation. Converting one into the other means answering a question the source file never asked, once for every cell.

That is where these tools differ from each other, and it is the only place they can. Reading commas is solved. Deciding that 41 is a quantity while 01234 is a postal code is not, and a converter that answers it silently hands you a file whose damage shows up two weeks later in someone else’s import log. This page puts every one of those answers on screen, on rows from your own file, before there is anything to download.

CSV and JSON, in brief

CSV
Full name Comma-Separated Values
Extension .csv
Format type Plain text table, one record per line
MIME type text/csv
JSON
Full name JavaScript Object Notation
Extension .json
Format type Nested text data, six value kinds
MIME type application/json

One type per column, or the column is text

Guessing per cell is the common approach and it produces output that looks correct in a preview: five hundred records where qty is a number, and three where it is the string "N/A" because somebody typed that in April. Nothing is wrong with the JSON. Everything is wrong downstream — a warehouse loader, a typed struct, a schema validator and a dataframe all want a field to mean one thing, and each of them fails at a different point with a different message.

So a column here is typed only when every non-empty cell agrees. A single disagreement makes the whole column text, and the value responsible is quoted back to you, so the decision is one you can inspect rather than one you have to reverse-engineer. Blank cells never count as disagreement; they are absence, not a conflicting opinion. When the guess is not what you wanted, each column carries its own selector — auto, text, number, boolean — and the sample line under it updates the moment you change it.

Zeros at the front, and digits past the fifteenth

Two number problems account for most of the corruption in this direction, and both of them are invisible until much later.

The first is the leading zero. 01234 is a ZIP code, an account reference, a product code or a phone number, and its first character carries meaning. Read as a number it becomes 1234 and there is no way back. Any column with a leading zero anywhere in it therefore stays text here. If you happen to know the column really is numeric, force it and you get the number — the point is that nobody does it on your behalf.

The second is quieter. JavaScript holds roughly fifteen significant digits, so the nineteen-digit identifiers that Snowflake, Twitter and many order systems hand out do not survive being read as numbers: 12345678901234567890 comes back as 12345678901234567000. This tool detects that a value cannot make the trip intact, writes it as a string, and shows you the number it refused to produce. It is the same promise the JSON to CSV converter makes traveling the other way, and the two pages are deliberately consistent about it, because a round trip that changes your identifiers is worse than one that fails.

Three shapes, and the one your pipeline actually wants

An array of objects is the default and the right answer when a person or an application will read the whole thing at once. It is also the wrong answer for a data pipeline, because a reader cannot process record one until the closing bracket has arrived.

NDJSON — one object per line, no wrapping array, no commas between records — is what log collectors, BigQuery loads and batch APIs expect, and it streams: a million records can be read line by line with constant memory, and a truncated file still yields every complete record before the break. The keyed object is the third form, turning the file into a lookup table on a column you choose. It is the only shape that can lose a record, since two rows sharing that value cannot both survive as keys, so the collision is counted and the offending value is named rather than left for you to discover.

What CSV to JSON does with a broken file

Real exports arrive damaged in a small number of recognizable ways, and all of them are survivable if the tool says what it did. Two columns headed the same thing cannot both be called that in an object, so the second is numbered. A blank header still names a real column full of values, so it is named after its position instead of vanishing. Rows that carry more fields than the header names — usually an unescaped quote or separator inside a value — keep their surplus under numbered keys rather than losing it, and rows that stop early are padded rather than shifted left, which is the difference between a gap and a file where every value after column three belongs to the wrong field.

Each of those messages quotes the text it found rather than citing a row number. That is deliberate. Our grid has none of the blank rows a spreadsheet draws, so what we would call row two is often your row three, and a number you cannot check against your own screen is worse than no number at all. Text you can search for. If you would rather look at the grid first, the CSV viewer opens the same file as a sortable table and flags the same hazards.

Three things only the file itself can tell you

Paste a table and it converts exactly the same way. But the paste box cannot report on encoding, on a byte order mark, or on line endings, and this is not a limitation we chose. A browser text area rewrites every CRLF to LF as it accepts the text, and reading a file as a string quietly swallows a byte order mark; by the time any code here could look, both facts are gone. So a dropped file is read as raw bytes and decoded here instead, which is why the encoding control and those three readings appear only in that mode. A carriage return inside a quoted value is real data, it ends up in your JSON as \r\n, and you deserve to know that before you diff the result against something else.

The encoding itself is the older half of the same problem. A file written as UTF-8 and read as Windows-1252 turns Malmö into Malmö, and once that has happened the mangled characters are what your JSON will contain. Detection runs first and the override exists because bytes written in Latin-1 can pass as UTF-8 purely by chance, and in that one situation nothing but your own eyes can settle it. If the file started life as a workbook, Excel to CSV is a cleaner first step than whatever Excel’s own save dialog produced, and the guide to the CSV format explains why the format has no standard to appeal to in the first place.

Where the work happens

Conversion runs in this page. The parsing, the type decisions and the writing are function calls in your own browser, there is no endpoint here that accepts a file, and a document larger than half a megabyte moves to a background thread so the tab stays responsive rather than freezing. Several other CSV to JSON converters work this way too, and say so honestly — the difference worth choosing between is not where the code runs but whether the file tells you what it decided. Watch the network panel while you drop a file if you want the first part confirmed; read the column list if you want the second. When the JSON that comes back needs inspecting or reindenting, the JSON formatter takes it from here.

Questions

Why is my ZIP code column text instead of numbers?

Because 01234 is not the number 1234. A leading zero is information — postal codes, product codes, phone numbers and account numbers all carry it, and a converter that reads them as numbers destroys the zero permanently. Any column with a leading zero anywhere in it stays text, the tool names the value that caused it, and if you know the column really is numeric you can force it to Number in the column list and get 1234.

What happens to a very long number, like a 19-digit ID?

It stays text, on purpose. JavaScript holds about fifteen significant digits, so 12345678901234567890 comes back as 12345678901234567000 from every converter that takes the obvious route, and that is silent corruption in exactly the columns that tend to be identifiers. This tool detects that the value cannot survive the trip, writes it as a string, and shows you what the other answer would have cost.

Can one column hold numbers in some records and text in others?

Not when the tool is guessing. A column is typed only if every non-empty cell carries the type, so one N/A among five hundred numbers makes the whole column text — and the cell that caused it is quoted so you can find it. Mixed types in one field are valid JSON and they are also what breaks the import at the other end, in BigQuery, in a Go struct, in a pydantic model. Empty cells never block a type; they are absence, not disagreement.

What is NDJSON, and when do I want it?

One JSON object per line, with no wrapping array and no commas between records. It is what log pipelines, BigQuery and OpenAI-style batch APIs read, and it is the only one of the three shapes that streams: a reader can process line one without having seen the end of the file. Pick the plain array when a person or a JavaScript app will read it, and the keyed object when you want to look records up by an ID rather than iterate them.

Does my file get uploaded anywhere?

No. The file is read with the browser’s own FileReader, decoded, parsed and written back out as JSON by JavaScript running on this page, and there is no endpoint here that accepts a file. Open the network panel before you drop one in and it stays empty. That matters more for CSV than for most formats, because a CSV export is usually a customer list, an order history or a payroll extract.