CSV to JSON in one paste. Clean output, zero friction.
Rowson converts CSV and TSV data to JSON in your browser. Paste it, pick your format, copy the result. Nothing to install, nothing to sign up for.
Here is a row that breaks naive CSV parsers:
id,name,note
42,"Alice "Smith"",valid customerThe second field has an unbalanced quote. PapaParse 5.4.1 raises a Quotes error reading “Trailing quote on quoted field is malformed” and still returns a row, but the note column gets pulled into the name field and the row count goes off by one. Rowson surfaces the first error in the status bar with the offending row number, so you see the failure instead of pasting silent garbage into your API.
This page walks 7 inputs that look fine until you parse them, what PapaParse 5.4.1 does with each, and what Rowson does on top.
Delimiter detection: how Rowson reads the first 5 rows
Rowson tries 4 delimiters in this exact order before falling back to comma: ,, \t, ;, |. The detection routine takes the first 5 non-blank lines and counts each candidate outside quoted regions, tracking an inQuotes toggle on the fly. It scores each delimiter as min_count_across_rows * consistency_bonus, where the bonus is 2 when min equals max and 1 otherwise. A delimiter that appears 3 times in every one of those 5 rows beats one that appears 5 times in row one and zero in row two. The Auto/Override toggle in the toolbar exposes the same 4 candidates, no more. Anything outside that set, like a record-separator byte or a custom multi-character delimiter, will not detect, and you'd need to pre-process the input. The detection is cheap and conservative on purpose. It doesn't sniff for known dialects or run statistical tests. It just counts.
Q: Does Rowson handle European exports with semicolons and decimal commas?
A: It picks up the semicolon delimiter automatically. It does not rewrite 1,5 into 1.5 inside a numeric field; values stay as strings and the receiver decides how to parse the locale.
Quoted fields with embedded newlines and commas
The RFC 4180 rule is that a field wrapping a newline must be double-quoted, and any literal double quote inside must be escaped by doubling: "". PapaParse implements this correctly on default settings. Two failure modes still come up.
id,bio
1,"Software engineer.
Loves cats and tabular data."
2,"Plain bio"PapaParse reads this as 2 data rows because it respects the opening quote on line 2 and keeps consuming until it finds the closing one. Rowson preserves the embedded newline inside the bio value and emits it in the JSON as a literal \n once JSON.stringify runs. The row count in the status bar stays at 2.
The second failure mode is a field containing a delimiter but not quoted. PapaParse splits on every comma and produces 4 columns from a 3-column header. With header: true, the extra field is stuffed under an undefined header key and disappears from the Record<string, string> row. Rowson emits a FieldMismatch warning, surfaced by row number in the status bar.
Inconsistent column counts and what gets dropped
Real exports drift. PapaParse reports TooFewFields or TooManyFields errors but still returns rows; data is keyed positionally to whichever headers line up.
id,name,email,plan
1,Alice,alice@example.com,pro
2,Bob,bob@example.com
3,Carol,carol@example.com,free,extra-column-valueRow 2 produces { id: "1", name: "Alice", email: "alice@example.com", plan: undefined }. Row 3 returns the same 4 keys plus the extra value gets dropped on the floor by header: true. Rowson's status bar shows the first error's row number prominently and keeps the parse result visible below it so you can see which row is short and which is over.
A BOM-prefixed file is the other classic export quirk:
id,name,plan
1,Alice,proThe invisible byte sits in front of the first header. PapaParse 5.4.1 strips the BOM automatically when present at position 0 of the input, so the first header parses as id rather than id. Earlier versions didn't. If you're moving from a pre-5.0 parser, this is one of the bugs that goes away for free.
JSONL vs. array-of-objects: what the format choice discards
The 4 output formats Rowson offers are not equivalent. Each one throws away some information that the original CSV had.
Array of objects is the closest thing to lossless within the JSON model. Every row becomes an object keyed by header name, and column order survives via ES2015 own-property ordering for string keys that don't look like array indices. JSONL emits one object per row separated by \n with no enclosing array, the format BigQuery's bq load, DuckDB's read_json_auto, and most streaming pipelines expect. The discarded structure is the closing wrapper: a partial JSONL file is still parseable line by line, a partial array-of-objects is not parseable at all.
Pipe-delimited input with embedded commas is the case that catches people the most:
name|tags|note
Alice|"premium,beta"|"comma, inside, note"PapaParse with the autodetected pipe delimiter handles this correctly because the commas live inside quoted fields. Rowson's detection picks up the pipe (3 occurrences per row, 0 outside-of-quote commas in the delimiter position), so conversion produces tags: "premium,beta" and note: "comma, inside, note". Array of arrays is the only output format that round-trips back to CSV cleanly. Array of objects loses column order in clients that re-sort keys alphabetically. Keyed object loses any rows that share a first-column value.
Keyed-object mode and the first-column assumption
Keyed object is the format that quietly drops data. The implementation uses headers[0] as the lookup key and writes each row in as { [firstColValue]: { ...row } }. Two rules follow from that one line.
user_id,plan,seats
1,pro,10
1,free,5Both rows have user_id: "1", and the keyed object comes out as { "1": { user_id: "1", plan: "free", seats: "5" } }. The first row is overwritten in place because object keys are unique. PapaParse reports no error here; nothing failed at the CSV layer. The lossy step is Rowson's format step.
A subtler trap is when the first column is a numeric ID. V8 stores integer-like string keys in numeric order regardless of insertion order, so a keyed object for input keyed by 1, 2, 10 comes out with 10 last even if it was the second row. Rowson does not work around this. It's a property of the JSON consumer, not the CSV.
,name,age
,Alice,30
,Bob,25That empty first header is the last snippet in the gallery. PapaParse parses the header as ["", "name", "age"] and produces rows where the empty-string key holds the first column's value. In keyed-object mode, headers[0] is "", so every row gets keyed under "" and you end up with one entry total. In array-of-objects mode the empty-string key is preserved on every row, valid JSON that breaks most consumers. The pattern we landed on, when this came up in our own test fixtures, was to use array-of-arrays output and let the downstream consumer assign its own header.
When we tested Rowson against a 12 MB CSV export from a Stripe customer dashboard, the cases that broke were the ones above: 4 rows with unbalanced quotes from a pasted address field, 2 rows with a missing column from a script change three months earlier, and a BOM in the file header that was invisible until JSON-LD validation downstream complained about an unexpected character.
None of these is exotic.
Q: Can Rowson handle TSV without me changing anything?
A: Yes. Tab is in the auto-detect set and wins for any input where the first 5 rows have at least one tab per row.
Q: What is the file size ceiling?
A: There is no hard ceiling because everything runs in the browser, but PapaParse runs synchronously in this build, so files over roughly 20 MB will lock up the main thread for visibly long periods.
No accounts. No data collection.
Rowson is free and ad-supported. There are no sign-ups and no email captures. We use PostHog for anonymous page-view analytics and that is it. Full details in the Privacy Policy.
Frequently asked questions
How do I convert a CSV file to JSON?
Paste your CSV into Rowson or drop a .csv file in. Rowson auto-detects the delimiter, parses the rows, and outputs JSON as an array of objects keyed by the header row. Click Copy JSON or Download .json to save the result. Everything runs in your browser — your data is not uploaded.
How do I convert CSV to JSONL (JSON Lines) for LLM training?
In Rowson, paste your CSV and switch the output format to JSONL. Rowson emits one JSON object per line with no wrapping array, which is the format expected by OpenAI fine-tuning, Hugging Face datasets, and BigQuery imports. Copy the output or download it as a .jsonl file.
How do I convert a tab-separated (TSV) file to JSON?
Paste the TSV content into Rowson. The converter auto-detects that fields are tab-separated and parses accordingly — no toggle needed. You can also manually override the delimiter to Tab if auto-detection misreads your data. Output is standard JSON.
Is there a free CSV to JSON converter with no signup?
Yes — Rowson is free, requires no account, no email, and no payment. There is no file size limit because conversion happens entirely in your browser. The tool is ad-supported to stay free.
How do I convert CSV to a JSON array of objects?
Rowson's default output format is an array of objects. Each row becomes a JSON object keyed by the header columns, and all rows are wrapped in a single array. For example, a CSV with headers name,age becomes [{"name":"Alice","age":30},{"name":"Bob","age":25}].
Does Rowson upload my CSV data to a server?
No. Rowson runs entirely in your browser using client-side JavaScript. Your CSV input, the parsed JSON output, and any file you drop in never leave your device. There is no server round-trip and nothing is logged.
What is the difference between JSON and JSONL (JSON Lines)?
JSON is a single document — typically one array containing all records. JSONL (JSON Lines) is one standalone JSON object per line with no wrapping array and no commas between records. JSONL is used for streaming pipelines, LLM training data, and BigQuery imports because each line can be processed independently.
How do I copy the converted JSON to my clipboard?
Click the Copy JSON button in the output pane. Rowson writes the full converted JSON to your clipboard and briefly shows a Copied confirmation. You can also download the result as a .json or .jsonl file using the Download button.