CSV ⇌ JSON converter
Paste or drop CSV and get JSON, or paste JSON and get CSV. Quoting, delimiters, headers, and types are handled in the browser — copy or download the result, nothing is uploaded.
Two formats, one table
CSV is what spreadsheets, exports, and data teams hand you: one record per line, fields separated by a delimiter, and a header row if you are lucky. JSON is what APIs, config files, and front-end code expect: named fields, real numbers and booleans, and nesting. Moving between them sounds trivial until a field contains a comma, a quote, or a line break, or a column of zip codes turns into integers and loses its leading zeros.
This converter goes both ways. Paste or drop a file and the direction is picked from the first character: input starting with [ or { is treated as JSON to CSV, anything else as CSV to JSON. Override it when the guess is wrong. Everything runs in your browser, with files above about 1 MB handed to a Web Worker so the tab stays responsive up to the 10 MB limit.
CSV to JSON
id,name,city,zip
1,"Ada, Countess",London,SW1A
2,Linus,Helsinki,00100[
{ "id": "1", "name": "Ada, Countess", "city": "London", "zip": "SW1A" },
{ "id": "2", "name": "Linus", "city": "Helsinki", "zip": "00100" }
]With the header option on, the first row becomes the keys of every object. Turn it off and the keys become column_1, column_2, and so on. The array-of-arrays shape skips keys altogether and gives you a plain matrix, which is smaller and convenient when you are feeding a charting library or a spreadsheet API.
Quoted fields with embedded commas, doubled quotes, and newlines inside a cell are handled by PapaParse, the same parser used by most browser-based data tools. Delimiter auto-detection covers commas, semicolons (the default in many European Excel locales), tabs, and pipes; you can also force one from the options.
Type inference, and why it is off by default
CSV has no types: everything is text. JSON does, so a converter has to decide whether 42 is a number and true is a boolean. Guessing is convenient and dangerous in equal measure. A zip code such as 02115 parsed as a number becomes 2115. A 17-digit order id becomes a floating-point approximation, because JSON numbers are IEEE-754 doubles and lose precision past 15 or 16 digits.
That is why inference is opt-in here, and why even with it on the tool refuses to coerce values with a leading zero (other than 0 itself) or more than 15 digits. When you enable it, 42 becomes a number, true and false become booleans, and empty cells become null.
sku,qty,active,zip,order_id
A1,3,true,02115,12345678901234567[
{
"sku": "A1",
"qty": 3,
"active": true,
"zip": "02115",
"order_id": "12345678901234567"
}
]What happens to messy files
Real exports are rarely clean, so the converter reports what it fixed instead of failing:
- Duplicate header names get a numeric suffix, so two
namecolumns becomenameandname_2rather than one overwriting the other. - Empty header cells become
column_N, using the original column position. - Short rows are padded with
nullfor the missing fields. - Rows with more cells than headers keep the overflow in an
_extraarray instead of silently dropping data. - A byte-order mark at the start of the file, common in Excel exports, is stripped so the first header does not come out as
id.
Each of these shows up as a notice above the output, so you know the shape of the data changed and can decide whether to fix the source.
JSON to CSV
[
{ "id": 1, "user": { "name": "Ada", "email": "ada@x.io" }, "tags": ["admin", "beta"] },
{ "id": 2, "user": { "name": "Linus" }, "tags": [] }
]id,user.name,user.email,tags
1,Ada,ada@x.io,"[""admin"",""beta""]"
2,Linus,,[]An array of objects becomes one row per object, with the header built from the union of every key seen, so records with different fields line up under a shared set of columns. Nested objects are flattened to dot-notation columns such as user.name when flatten is on; arrays are kept as a JSON string in a single cell because a flat table has nowhere else to put them. An array of arrays is written as-is, and a single object becomes a one-row table.
The output options match what downstream tools expect: choose the delimiter, switch line endings to CRLF for Windows and older Excel versions, and quote every field if a strict importer needs it. The download adds a byte-order mark so Excel opens accented characters correctly.
Where it fits
- Turning a spreadsheet export into fixture data or a seed file for a test suite, with inference on so numbers are numbers.
- Getting an API response into Excel or Google Sheets for someone who does not read JSON, with flatten on so nested fields become columns.
- Checking what a CSV actually contains before importing it: the row and column summary and the notices catch ragged rows and duplicate headers early.
- Converting semicolon-delimited European exports to plain comma-separated files that a script expects.
From JSON, the JSON, YAML and TypeScript converter takes you on to a typed interface, and the Markdown table generator accepts the same CSV when the destination is a README or a pull request.
CSV and JSON, both directions, in the browser
Spreadsheets speak CSV. APIs speak JSON. This converter sits in between: paste a table or drop a .csv / .json / .txt file and get the other format back, ready to copy or download. Input that starts with [ or { is treated as JSON going to CSV; everything else is parsed as CSV going to JSON. Override the direction when auto-detect guesses wrong. Conversion is fully client-side, including a Web Worker for files above about 1 MB, so a 10 MB export will not freeze the tab and will not leave your machine.
Type inference gotchas
Inferring types looks convenient until a zip code or a database ID is involved. JSON numbers are IEEE-754 doubles: they cannot keep a leading zero, and they lose precision past 15–16 digits. That is why inference is off by default, and why even with it on this tool refuses to coerce values that start with a zero (other than 0 itself) or that have more than 15 digits.02115 stays a string. A 17-digit order ID stays a string. 42, true, and empty cells still become a number, a boolean, and null when you opt in. If you round-trip CSV → JSON → CSV with matching options, the data comes back equivalent — quoting may differ, the values do not.
CSV parsing uses PapaParse, which is what you want for the cases people actually hit: quoted commas, quotes inside quotes, and newlines inside a field. Semicolon files from Excel European locales are auto-detected. Duplicate headers become name_2; empty headers become column_N; short rows pad with null and leftover cells land in _extra instead of failing the whole file.
FAQ
Is my data uploaded?
No. Parsing runs in a worker in your browser, including files up to 10 MB. The CSV or JSON never leaves your device.
What is the maximum file size?
10 MB. Above about 1 MB the conversion is handed to a Web Worker so the tab stays responsive while PapaParse does the work.
Will semicolon CSVs from Excel convert?
Yes. Delimiter auto-detect picks up commas, semicolons, tabs, and pipes. You can also force a delimiter from the options row.
Why are my zip codes strings?
Type inference is off by default, so 02115 stays "02115". Turn inference on for numbers and booleans — leading zeros and 16+ digit IDs still stay strings, because JSON numbers cannot represent them faithfully.