Skip to content

Convert CSV to JSON, and JSON back to CSV

Going one way, each row becomes an object whose names come from the header, and you choose whether a numeric looking cell is written as a number and whether a blank cell is an empty string or a null. Going the other way, a list of records becomes a table whose columns are every name that appears anywhere, with anything nested written back as compact JSON in the cell. Values keep the characters they were written with in both directions.

In your browser

Turn a CSV into JSON, or JSON back into a CSV

Rows in, records out, or the other way round. The delimiter is worked out from the file, the header row becomes the names, and nothing goes through a floating point number on the way, so a long order reference arrives with all of its digits and a leading zero is still there.

Your file is not uploaded. It is read by this page, in a background task beside it, and there is no code here that could send it anywhere. Both directions keep values as the text they were written as rather than putting them through a number, which is what stops a long identifier being rounded and a price written with a trailing zero losing it.

CSV and JSON converter, step by step

  1. Choose the directionRows to records, or records back to rows. The panel changes to offer only the switches that mean anything in that direction.
  2. Paste it, or choose a file for the CSV sideA file is read a megabyte at a time rather than all at once, so a large export does not have to be pasted into a box.
  3. Set the switches, then convertWhether numbers lose their quotes, whether blanks become null, and which separator to read or to write.
What it actually does

The four things a table cannot say, and what this does about each of them

A table and a document are not the same shape, and every converter has to make four decisions about the difference. The first is types: a cell has none, so something has to decide whether the characters 1.50 are a number or a piece of text. That is a switch here, and even switched on a value with a leading zero stays text, because 007 is a reference code and turning it into seven destroys the column. The second is absence: a table cannot distinguish an empty cell from a missing one, so which of an empty string and a null it becomes is also a switch rather than a house style. The third is nesting: a document can hold a list inside a record and a table cannot, so going that way anything nested is written into the cell as compact JSON, which is ugly and reversible, where flattening it into extra columns is neat and not. The fourth is names, and it is the one that quietly loses data elsewhere: two columns called id are ordinary in a joined export and an object can only hold one of them, so the second is renamed rather than written over the first. On top of all four, nothing is ever put through a floating point number, so a long reference arrives with all its digits.

Two shapes for the same data, and the conversion between them is the sort of job that looks finished long before it is. Splitting on commas and joining with braces gets you something for the first file you try and falls apart on the second, because the awkward parts of both formats are exactly the parts a quick version skips.

On the CSV side that means quoting: a field can hold commas, line breaks and quote marks of its own, and half the exports in the world use semicolons rather than commas in the first place. On the JSON side it means shape: a document can nest and a table cannot, so something has to be decided about that and the only bad answer is deciding it quietly.

The reader used here is the same one behind the CSV viewer, and the JSON reader is the same one behind the formatter, which is the point of them being separate pages built on shared parts. A second copy of either would eventually read a file differently from the page next door, and neither page would fall over while it happened.

Questions

Why has every value come out as a string?

Because a cell in a table has no type, so the honest default is to leave everything as the text it was. Tick the switch and anything matching JSON's own definition of a number loses its quotes, along with the words true and false. It is off by default because guessing is how a column of postcodes or product codes gets turned into arithmetic, and once that has happened the original is gone.

What happens to a value with a leading zero?

It stays as text, even with type conversion switched on. A leading zero is how a reference number, an account number or a phone number is written, and JSON has no way to keep one on a number, so writing 007 as a number gives you back 7 and the column no longer means what it did. The rule used is JSON's own grammar for a number, which does not allow a leading zero either.

My document is a list inside an object called data. Will that work?

Yes. That is the shape almost every API response arrives in, and refusing it would send you off to hand edit the file before you were allowed to use the page. When a document is a single object holding a single list, the list is used as the rows and the panel says which name it took them from, so the unwrapping is visible rather than silent.

Can I convert one way and then back again and get what I started with?

For a flat table with no types, yes, and it is asserted in the tests rather than promised here. Once anything is nested, or a column has been turned into numbers, the round trip stops being exact in a way no converter can avoid, since a table has nowhere to keep a list, and a number written 1.50 in a cell is 1.5 as a number, which is why type conversion is a switch you have to reach for.