Polyatic CSV ⇄ JSON Converter

CSV ⇄ JSON Converter

Convert CSV to JSON and JSON back to CSV live, with correct quote, delimiter and newline handling. Nothing is uploaded.

CSV input

Pick the delimiter your file uses. First row is header maps columns to object keys; turn it off for an array-of-arrays. Infer types is off by default (every value stays a safe string); turn it on to coerce numbers and true/false to real JSON types.

Output JSON


        

Runs entirely in your browser — your data never leaves your device. Parsing and conversion use a small script you can read; there are no network requests and no analytics on this tool.

What this tool does

Paste a CSV file (or a JSON array) into the box on the left and the converted result appears on the right the instant you stop typing — there is no button to press. Switch the direction toggle to go the other way; when you flip it, the current output is loaded back as the input, so you can round-trip a file and confirm it survives the trip. A live meter reports how many data rows and columns were detected, and any parse problem is shown inline in red rather than throwing an error or clearing your work.

Worked example: three rows in, one JSON array out

Take this CSV — a header plus three data rows, including one field with an embedded comma:

name,role,city
Ada Lovelace,Engineer,London
"Smith, John",Manager,"New York, NY"
Grace,Admin,Paris

With First row is header on and comma as the delimiter, you get an array of three objects. Minified (Pretty-print off) it is exactly:

[{"name":"Ada Lovelace","role":"Engineer","city":"London"},
{"name":"Smith, John","role":"Manager","city":"New York, NY"},
{"name":"Grace","role":"Admin","city":"Paris"}]

Two things to notice. The quoted field "Smith, John" survives as one value — the comma inside the quotes is not a column break — and "New York, NY" does the same. And every value is a JSON string: there is no number or boolean in that CSV, but even if a column held 42 or true it would arrive quoted, because CSV carries no type information (more on that below).

How the CSV parser handles the awkward cases

Real-world CSV is messier than "split on commas". This parser implements the RFC 4180 quoting rules character by character, so it copes with the cases that break naive splitters:

  • Embedded delimiters: "Smith, John" stays a single field even though it contains a comma.
  • Embedded newlines: a quoted field may span several lines — a multi-line address in one cell is kept intact.
  • Escaped quotes: a literal double-quote is written as two ("") inside a quoted field and is turned back into one, so "She said ""hi""" becomes She said "hi".
  • Line endings: both \n (Unix) and \r\n (Windows) row terminators are accepted.

Pick the delimiter your file actually uses — comma is standard, but European exports often use a semicolon (because the comma is their decimal point) and spreadsheet copy-paste usually gives you tabs.

Header vs headerless

With First row is header on (the default), the first CSV row supplies the property names and every later row becomes an object — the familiar [{"name":"Ada",…}, …] shape most APIs expect. Turn it off and each row becomes an array instead, giving an array-of-arrays that mirrors the raw grid, first row included. Going from JSON to CSV, an array of objects is flattened to columns using the union of every object's keys (in first-seen order), so rows with missing keys get an empty cell.

Type inference: strings by default, real types opt-in

CSV carries no type information, so the safe default is every value stays a string. That guarantees a lossless result: a ZIP code like 07030, a version like 1.10 or an ID like 0x1F is preserved exactly instead of being turned into a number that drops the leading zero, the trailing digit, or the whole meaning. Leaving Infer types off is the right call whenever the data is really identifiers, codes or mixed text.

When you do want real JSON types, turn on Infer types. It applies this exact, fixed ruleset to each cell — nothing more, nothing guessed:

  • Integers and decimals → number, but only when the value round-trips exactly (see the guard below). 42 becomes 42 and 3.14 becomes 3.14.
  • true / falseboolean, and only those two exact lowercase spellings. True, TRUE, yes and 1 all stay strings, because CSV has no agreed boolean convention and guessing is where silent corruption starts.
  • Empty cell → the pinned default. By default an empty cell becomes an empty string ""; switch the Empty → menu to null if your consumer expects that instead. (The default is "".)
  • Everything else stays a string — dates, currency, phone numbers, anything with letters or punctuation.

The information-loss guard (why this is safe)

A value is coerced to a number only if converting it and printing it back yields a byte-identical string — formally, String(Number(cell)) === cell. If that check fails, the cell stays a string. This single rule is what keeps type inference honest, and it blocks exactly the cases that would silently lose data:

  • 007 stays "007" — a leading zero can never round-trip, so ZIP codes and IDs are safe.
  • 1.10 stays "1.10" — the trailing zero would be dropped to 1.1.
  • 9007199254740993 stays a string — it is larger than 253, so it cannot be held exactly in a JSON/IEEE-754 double and would round to a different number.
  • Infinity, NaN, 0x1F, 1,000 and 1e3 all stay strings — none is a canonical JSON number that round-trips.

In the JSON→CSV direction the reverse holds regardless of this toggle: real numbers, booleans and null are written in plain text form, with null becoming an empty cell.

CSV vs JSON vs NDJSON

Three formats you will meet constantly, and when each earns its place:

FormatShapeTypes & nestingBest for
CSVFlat rows & columnsNo types, no nestingSpreadsheets, quick exports, columnar data
JSONOne tree (here, an array)Typed, fully nestableAPIs, config, structured records
NDJSONOne JSON object per lineTyped, nestable per lineLog streams, append-only exports, big data

This tool converts CSV to a single JSON array (and back). To produce NDJSON, convert here, then join the array's elements with newlines — one object per line, no wrapping brackets or commas.

Common mistakes

  • Wrong delimiter. A semicolon file read as comma-delimited comes out as one giant column. Match the delimiter menu to the file.
  • Expecting numbers. By default "age":"42" is intentional, not a bug — strings are the safe default. Turn on Infer types if you want 42 and true as real JSON types.
  • Un-doubled quotes. A stray single " inside an unquoted field confuses any RFC 4180 parser; inside a quoted field, write a literal quote as "".
  • Ragged rows. Rows with more or fewer fields than the header line indicate a quoting error somewhere above — usually an unterminated quote swallowing later rows.

Honest limits

CSV is flat, so it cannot express nested JSON. When a JSON value is itself an object or array, this tool writes that cell as a compact JSON string rather than exploding it into extra columns — the data is preserved and reversible, but it is not deep-flattened into dotted column names. Everything runs on your own device: the page loads no third-party scripts and makes no network calls, so a spreadsheet export or an API payload you paste in stays in the tab and is gone when you close it. Very large files (tens of megabytes) may briefly freeze the tab, because the work runs synchronously on the main thread.