CSV to JSON

Turn a CSV table into a JSON array of objects.

Reverse
Input
CSV input
Output
Result
Options

Detected automatically unless you pick one.

Values with leading zeros stay strings so IDs are preserved.

Spaces per level of nesting.

Further reading

  • How to convert CSV to JSONConvert CSV to JSON reliably: trimmed headers, type inference, empty cells, quoted fields, ragged rows and why dotted column names stay flat.

About this tool


Parsing CSV correctly is harder than it looks. Commas inside quoted fields, doubled quotes, line breaks within a value, a header row that repeats a name, and rows with the wrong number of fields all appear in real exports. This converter handles each of them and tells you when it had to make a judgement call.

The output is a JSON array of objects, with each header becoming a key. That is the shape APIs and JavaScript code expect, and it is what makes a CSV export usable as a fixture, a request body, or seed data.

How to use it

  1. Paste or upload CSVDrop a .csv file or paste the rows directly.
  2. Confirm the header settingThe first row is treated as column names by default. Turn that off for a headerless file and columns are named column_1, column_2, and so on.
  3. Choose type inferenceLeave it on to get real numbers and booleans, or turn it off to keep every value as a string.
  4. ConvertPress Convert to JSON, or use Ctrl+Enter.
  5. Read the warningsWarnings cover renamed duplicate headers and rows whose field count did not match.

Worked examples


Each example below is executed against this tool by the test suite, so what you see is what the tool actually produces.

Quoted commas and type inference

Input

id,name,note,active
1,Alice,"lives in Paris, France",true
2,Bob,,false

Output

[
  {
    "id": 1,
    "name": "Alice",
    "note": "lives in Paris, France",
    "active": true
  },
  {
    "id": 2,
    "name": "Bob",
    "note": "",
    "active": false
  }
]

The quoted comma stays inside its value; ids become numbers and active becomes a boolean.

Leading zeros preserved

Input

zip,qty
01234,42

Output

[
  {
    "zip": "01234",
    "qty": 42
  }
]

The zip code stays a string so the leading zero survives; the quantity becomes a number.

What to watch for


The details that decide whether a conversion is correct, and where information can be lost without any error being raised.

Quoted fields, doubled quotes and embedded newlines
A field wrapped in double quotes may contain the delimiter, line breaks, or quotes escaped by doubling them. So "x, y" is one value containing a comma, "has ""quotes""" becomes has "quotes", and a quoted field spanning two lines stays one value with a newline in it. This is RFC 4180 behaviour and the reason splitting on commas by hand fails on real data.
Duplicate headers are made unique, not dropped
CSV allows the same column name twice; a JSON object cannot have duplicate keys. Rather than silently losing a column, the second occurrence is suffixed: name and name become name and name_2. The warning lists every rename so you know which column is which. Blank header cells become column_1, column_2 and so on by position.
Type inference is deliberately conservative
Values that are unambiguously numbers become numbers, true and false become booleans, and the literal null becomes null. Anything that could be an identifier stays a string: 007 keeps its leading zero, +44 7700 stays text, and an integer too large for JavaScript to represent exactly is left as a string rather than silently rounded. This is the behaviour you want for IDs, phone numbers and postal codes.
Ragged rows are reported, never silently truncated
If a row has more fields than the header, the extras cannot be named and are dropped, with a warning saying so. If it has fewer, the missing keys are filled with empty strings, or null if you prefer. Either case usually means a quoting problem upstream, so the warning is worth reading.
Empty cells: string or null?
By default an empty cell becomes an empty string, which matches what the file literally contains. Switch on "Treat empty cells as null" when a blank means "no value" rather than "the empty string", useful when the JSON feeds a database import.
Delimiters and line endings
The delimiter is detected automatically, so comma, semicolon, tab and pipe files all work; European exports using semicolons are common. Both LF and CRLF line endings are handled, and a UTF-8 byte order mark at the start of the file is stripped so the first column name is not corrupted.

Limitations


  • Cannot infer nested structure; a dotted column name stays a flat key.
  • Fields beyond the header count are dropped, with a warning.
  • An empty cell cannot be distinguished from an explicitly empty value in the source.
  • Processing happens in your browser, so very large inputs are bounded by available memory. Files above roughly 10 MB are handled but will feel slower, and multi-hundred-megabyte files are better suited to a command-line tool.

Questions


Can it produce nested JSON?
Not automatically, because CSV has no nesting to read. A column literally named user.name becomes the key "user.name" rather than a nested object, reshape afterwards if you need real nesting.
Why is my ID still a string?
Values with leading zeros, or integers too large for JavaScript to hold exactly, are kept as strings on purpose. Converting 007 to 7 or rounding a 19-digit ID would corrupt the data.
My file uses semicolons. Do I need to change anything?
No. The delimiter is detected automatically, which covers semicolon files from European Excel locales, tab-separated files and pipe-delimited exports. You can also set it explicitly in Options.
What if my CSV has no header row?
Turn off "First row contains column names" and the columns are named column_1, column_2 and so on, with the first row treated as data.