About CSVFormat
What this is
One textarea in, one textarea out. Paste CSV, get either a JSON array of objects or a list of SQL INSERT statements. The parsing, conversion, and formatting all run in your browser; nothing is uploaded, and the output pane is read-only by design.
The parser is a character-by-character state machine, not split(","). That distinction is the whole reason this tool exists, and it is RFC 4180 §6 that makes it necessary: fields containing line breaks, double quotes, or commas should be enclosed in double quotes. Payment exports and spreadsheet saves do this constantly.
What the parser handles — measured, not claimed
I ran these through the shipped parseCsv rather than describing what it should do:
| Input | Result |
|---|---|
"line1 newline line2" in a quoted field | One field, one row. Column count stays correct. |
"He said ""hi"", loudly" | One field: He said "hi", loudly |
"Connor, John" | One field. Comma inside quotes does not split. |
| CRLF line endings | Tolerated; \r is skipped everywhere outside quotes. |
| Blank line in the middle of a file | Dropped. Not counted as a row, not reported ragged. |
| Trailing newline | Dropped. |
| Row with 2 fields against 3 headers | Counted as ragged; surfaced as a warning in SQL output. |
Embedded newlines are the case that quietly ruins naive tools. A quoted field containing a newline makes split("\n") produce the wrong column count, and the failure is invisible: the output looks like data.
Four places this tool deviates from RFC 4180
The spec is short and I read it against the source. These are real differences, each reproducible:
1. It trims every field, including inside quotes. RFC 4180 §4 says plainly: "Spaces are considered part of a field and should not be ignored." This tool ignores them. 1,[red] parses to [red], and even 1," keep" parses to keep — quoting does not protect your padding. If leading spaces are meaningful (indentation in a text column, alignment you are reconstructing), this is the wrong tool for that column.
2. Tabs are stripped too, same mechanism. 1,\tx\t parses to x.
3. Whitespace-only fields collapse to empty strings. 1, yields "". You cannot distinguish "cell contains three spaces" from "cell is empty".
4. Only comma is a delimiter. Semicolon-separated files — the default in several spreadsheet locales — parse as a single column: a;b becomes one header named a;b, silently, with no warning. Convert to comma-delimited first.
The trimming is a deliberate trade, not an oversight: trailing whitespace on every cell of a pasted spreadsheet is more often an accident than an intention. But it is a trade, and the spec side of the trade wins on the letter of the law.
JSON mode: what it will not do
The first row becomes object keys; each later row becomes one object.
- Every value is a string.
42becomes"42", dates stay dates-shaped strings. No type inference, because inference is how01234silently becomes the integer1234and your ZIP codes lose their leading zeros. Preserve that behaviour by typing them yourself downstream. - Ragged rows are padded or truncated without a flag. A short row gets
""for missing columns. A long row has its extra values dropped — the object can only hold keys it found in the header. Check the row counter before trusting a ragged file in this mode; the explicit warning appears in SQL output, not here. - Duplicate header names collapse. Two columns both named
idproduce oneidkey holding the last value.
SQL mode: read this before you run it
Each row emits one standalone INSERT INTO records (...) VALUES (...);. The table name is hardcoded to records, and there is no batching, so 50,000 rows means 50,000 statements.
Numeric detection is a round-trip test — a value is unquoted only if Number(v) is finite. That keeps 1e5 a number and keeps "1,200" a quoted string. It also produces results you need to look at before executing:
| Cell | Emitted as |
|---|---|
01234 | 1234 — leading zero gone |
007 | 7 |
0x10 | 16 |
+42 | 42 |
9007199254740993 | 9007199254740992 — precision lost |
2026-01-05 | '2026-01-05' — quoted, correct |
1.2.10 | '1.2.10' — quoted, correct |
The hex and integer cases are the dangerous ones. 01234 is a ZIP code or a product code far more often than it is the number one thousand two hundred thirty-four, and SQL integer literals have no leading zeros. Values above 2^53 arrive already rounded, because JavaScript parsed them as doubles on the way through.
Column names that are not bare identifiers get double-quoted. Column names that are bare identifiers are passed through unquoted — which breaks on reserved words. INSERT INTO records (order, b) VALUES (...) is rejected by SQLite with near "order": syntax error. Rename the column, or quote it by hand.
Single quotes in values are doubled (''), which is correct SQL escaping. What that does not make safe is the general case of piping generated SQL into a database you care about — for that you want parameters, which no browser tool can give you.
Performance
I parsed synthetic files in Node on the machine that builds this site:
| Shape | Size | Time |
|---|---|---|
| 1,000 × 5 | ~40 KB | 3 ms |
| 10,000 × 8 | 0.6 MB | 16 ms |
| 50,000 × 10 | 4.2 MB | 60 ms |
| 200,000 × 10 | 18 MB | 200 ms |
A few tens of thousands of rows paste and convert without a perceptible pause. The wall you will actually hit is your clipboard and browser textarea, not the parser.
Deliberately not here
No file upload, no drag-and-drop, no disk access. No delimiter or quote character options. No type coercion. No CSV writing direction. No server component — which is also the privacy story: a CSV pasted here never leaves this tab.
Related tools on the same machine: JSONBeautify for the JSON this tool can emit, SQLFormat for the SQL it can emit, cURLParse for API responses, RegexCalc when a column needs pattern surgery, and CSSTidy for something entirely different.