The export that opens as a wall of curly braces
The engineer hands you a file called events.jsonl and says it's the data you asked for. You double-click it. Excel squints, decides everything is one column, and renders a screen-length of braces, quotes, and escaped characters — twelve thousand rows of "what is this" with the actual information buried inside like raisins in concrete.
Nothing is wrong with the file. JSON Lines is the format that event pipelines, logging systems, and machine-learning workflows speak by default, because it streams beautifully — one record per line, append-friendly, readable with a text editor. It's just a format built for programs, and the program you wanted to hand it to was a spreadsheet.
This converter is the translator between those two worlds. Drop in the .jsonl, and nested records get flattened into named columns, mismatched keys get reconciled into a full header row, commas and quotes get quoted correctly under RFC 4180, and what comes out is a clean CSV that opens in Excel, Sheets, or your analytics tool as an honest table — with the whole operation running on your machine and your data never leaving it.
From curly braces to clean columns
Load the JSONL
Drag the file in or paste raw lines. The reader takes .jsonl, .ndjson, and plain .json arrays, and detects which shape it's looking at automatically.
Preview the flattened table
The first 100 records appear as a grid, with dot-path column names like user.name and event.query — so you see exactly what the CSV will look like before writing 12,000 rows.
Set the flattening rules
Choose whether arrays serialize to JSON text or drop out entirely, whether to prune columns present in fewer than a chosen share of records, and which columns to exclude outright.
Pick the CSV dialect
Comma or semicolon delimiter for your locale's Excel, UTF-8 BOM on or off, header row on or off. The defaults suit the widest range of software.
Convert and download
The full file processes in one local pass — a 2.4 MB log takes about two seconds — and downloads with a report showing record counts, skipped lines, and the column census.
What JSON Lines actually is
The rule fits in one sentence: each line is a complete, self-contained JSON object, and the newline character between lines is the only delimiter. No outer array, no pretty-printing across lines, no trailing commas. If any single line were lifted out of the file, it would parse as valid JSON all by itself — that property is the entire design.
The format has two documented ancestries worth citing precisely. The community spec lives at jsonlines.org and ndjson.org, which codified the conventions — UTF-8, one object per line, \n line terminator, blank lines ignored. On the standards track, the IETF's RFC 7464 defines JSON Text Sequences, the closely related newline-delimited framing for streaming JSON documents; each line's payload is an ordinary JSON text as defined by RFC 8259. Logging frameworks, Kafka pipelines, database export tools, and LLM training-data pipelines all converged on some dialect of this — which is why the file in your downloads folder has an .jsonl extension and no explanation.
The reasons for the convergence are practical. You can process a JSONL file line by line with constant memory instead of loading a monolithic document. You can append records forever without rewriting the file. One malformed line can be skipped while the rest of the file survives. None of those virtues matter to a spreadsheet — which is exactly why the two formats keep meeting in converters.
{"ts":"2026-04-03T09:14:22Z","user":{"id":8123,"name":"Ana Ruiz"},"event":"login"}
{"ts":"2026-04-03T09:15:40Z","user":{"id":9051,"name":"Ben Okafor"},"event":"search","query":"sourdough starter"}
{"ts":"2026-04-03T09:16:03Z","user":{"id":8123,"name":"Ana Ruiz"},"event":"view","page":"/recipes/419"}Flattening: how a tree becomes a grid
A CSV is a grid; a JSON record is a tree. The bridge is dot-path flattening: every leaf value in the tree gets a column named by the path from the root, joined with dots. The user object's name key becomes the column user.name; a deeper billing.address.city becomes billing.address.city. The nesting depth doesn't matter to the algorithm, only to the length of your column headers.
Arrays are the awkward relative. A scalar becomes one cell cleanly, but an array of three values has no single-cell representation that keeps all three — so the default is to serialize the array as compact JSON text in its cell (the value ["a","b"] lands as ["a","b"]), which is lossless and honest, if unaesthetic. The alternative is dropping array columns entirely when they're noise — tags, histories, and debug stacks that would bloat every row.
ts,user.id,user.name,event,query,page
2026-04-03T09:14:22Z,8123,Ana Ruiz,login,,
2026-04-03T09:15:40Z,9051,Ben Okafor,search,sourdough starter,
2026-04-03T09:16:03Z,8123,Ana Ruiz,view,,/recipes/419Notice what happened to the missing keys: Ana's login event has no query, so that cell is simply empty. That restraint — empty string for absent, not an error, not the literal text undefined — is what makes ragged real-world logs convertible at all. The deeper logic of sparse columns gets its own section below, because it's the part of this job that surprises people.
The union-of-headers problem
Textbook data has the same fields in every record. Real exports don't. An event log where searches carry a query field, views carry a page field, and errors carry a stack field produces records with three different key sets — and a CSV header must cover all of them. The standard solution is the union of headers: scan every record, collect every distinct flattened path, and make each one a column.
The interesting part is what this does to file shape. A 12,000-line log with 19 core fields can easily union out to 31 columns when twelve rare fields appear sporadically — an experiment flag set on 40 lines, a referral code on 7, a legacy payment_method field on 3. The CSV becomes mostly-empty columns, which is correct but ugly, and it's why the converter reports a column census: presence percentage for every column, with a pruning threshold you control.
Dropping the sparse tail is usually right for analysis — columns present in under half a percent of records are usually artifacts, not signals. Keeping them is right for auditing, where the 7 rows with referral codes might be exactly what you're hunting. The tool's answer is to make it a visible setting rather than a hidden opinion, and to tell you exactly which columns were pruned when it's done.
The quoting rules that keep CSV alive
CSV looks like a kindergarten format until the day a value contains a comma, at which point it reveals itself as a format with exactly three rules, formalized in RFC 4180. One: a field containing a comma, a double quote, or a line break must be wrapped in double quotes. Two: a literal double quote inside a quoted field is escaped by doubling it. Three: everything else is written as-is. That's the whole law, and the law is what stands between your data and a spreadsheet with 9,001 columns.
id,name,note
7,"Ruiz, Ana","replied ""yes"" by email"
8,Okafor,searched "sourdough starter"Read that second line the way a parser does: the quotes around Ruiz, Ana protect the comma from being a separator; the doubled "" inside the note is one literal quote character, restored on read. Every database, notebook, and spreadsheet imports this correctly — as long as the writer got it right, which hand-built converters with string concatenation famously don't. This one follows the RFC exactly, including the line-break-in-a-field case that breaks naive line-splitting code.
Two Excel rituals deserve their own paragraph, because they account for most "your converter broke my file" reports that are actually Excel being Excel. First, delimiter: Excel splits on the locale's list separator, so files written with commas open sideways in Germany or Brazil, where the separator is a semicolon — the export panel lets you choose. Second, encoding: Excel guesses character encodings badly, and UTF-8 without a BOM can render é as é — so the tool prepends the byte-order mark by default, the internationally recognized signal for "this is UTF-8, stop guessing."
A real log, end to end
Input
File: events.jsonl · 12,000 lines, 2.4 MB · 19 core keys across all records · 12 rare keys present in 0.03% to 1.4% of lines · longest single line 3,940 bytes (an error-stack record)
Output
Union of headers: 31 columns · Full CSV: 1.9 MB, opens as a clean table in Excel and Sheets · With sparse pruning at 0.5% presence: 9 columns dropped, 22 remain, 1.6 MB · Runtime: 2.1 seconds in-browser, zero network activity
The census is where the story is. Those twelve rare keys included a debug_mode flag (on 14 lines), two versions of an A/B experiment field (v2 won, 168 lines vs 9), and a payment_method remnant from a deleted checkout path (3 lines). In the spreadsheet those are five empty columns and three interesting questions — and this is the honest division of labor: the converter shapes the data; the analyst still gets to wonder about it.
For the pipeline-minded, the same job at the command line is csvkit's in2csv or a five-line Python script with json.loads and csv.writer. Those are good tools. The difference here is the census, the preview, the pruning dial, and the fact that a 2.4 MB log of user behavior never needs to be uploaded to a web service to become a table your team can argue about.
The cases that need judgment
- Mixed types in one column. Line 4 has "user_id": 8123; line 11,976 has "user_id": "8123" — number and string of the same value. The tool preserves each record's original representation and flags the column as mixed, with a coercion option if you want uniformity. Silent coercion is how spreadsheets corrupt IDs into scientific notation; flagging is how converters stay honest.
- null, empty string, and missing are three different states. A null value, an empty string, and an absent key all look identical in a CSV cell — nothing. The converter offers a literal marker option (for example writing NULL) when the distinction is data, not accident.
- Duplicate paths after flattening. A record containing both {"a":{"b":1}} and {"a.b":2} flattens two values onto one column name. JSON allows it; a grid doesn't. The collision is reported with line numbers rather than resolved by guessing.
- Arrays that eat the row. A messages array with 400 entries serialized into one cell makes a 60 KB "spreadsheet row." Prune array columns when they're debug noise; keep them when they're the payload — and know which yours are before exporting.
- One giant line. A 50 MB single line is almost never JSONL — it's a pretty-printed or minified JSON array. The detector routes it to the array path instead of dying on a memory spike, but a hint in the file name would have saved everyone a second.
- Encoding stowaways. Latin-1 bytes in a nominally UTF-8 file surface as mojibake; the reader tolerates and flags them rather than aborting at line 3 of 12,000. BOMs at the head of the file are stripped automatically.
- Trailing debris. Blank last lines, a stray footer row the exporter wrote, CRLF vs LF line endings — all absorbed. The report counts everything it skipped so surprises remain visible.
Who drops files on this page
- Data analysts handed .jsonl exports from product event pipelines and needing the familiar grid for pivots, filters, and pivot-chart arguments with marketing.
- ML engineers inspecting fine-tuning and evaluation datasets — question/answer pairs, prompt logs, scored outputs — before a training run consumes them.
- Support and operations leads converting ticket, chat, and call logs into spreadsheets for quarterly reporting.
- Data journalists opening public-data releases that agencies publish as NDJSON because their pipelines demand it, with readers on deadline who demand Excel.
- Developers sanity-checking their own logging output: the preview grid doubles as a fast eyeball pass over what the code is actually emitting.
- Students and researchers converting collected data for R, SPSS, or whatever their methods course requires — one less Python environment to install tonight.
The surrounding bench covers the rest of the format's relatives: plain JSON to CSV conversion for document-shaped files, Nested JSON to CSV when the nesting is the whole story, and the JSONLines to JSON tool when you want the whole array pretty-printed instead of tabulated. Round-tripping back to JSONL — common after spreadsheet edits — is the CSV to JSONL Converter, which handles the reverse direction including type inference.
Four ways to turn JSONL into a table
| This converter | csvkit (in2csv) | Python + pandas | Cloud converters | |
|---|---|---|---|---|
| Setup | None — a browser tab | pip install and a terminal | An environment and a notebook | An account, usually |
| Your data | Stays on your machine | Stays on your machine | Stays on your machine | Uploaded to their servers |
| Column census and pruning | Built in, visual | jq gymnastics | A few lines of code you write | Rarely offered |
| Bad-line recovery | Quarantine with line numbers | Depends on flags | Your try/except discipline | A failed job email |
| Excel dialect options | One click | Flags to memorize | Options to memorize | Sometimes |
| Best for | Getting to analysis in seconds | Scripted, repeatable pipelines | Analysis as the destination | One-off desperation |
If you're converting the same export every Monday, write the script — automation is the right answer to routine. For the other ninety percent of occasions, the ones where a file lands on your desk at 4:55 p.m. and someone wants numbers by standup, a tab that flattens, quotes, prunes, and never uploads is the tool that fits the tempo of the actual work.
Log files are personal files
It's worth pausing on what JSONL usually contains: not abstract data, but records of what humans did — searches, purchases, locations, support conversations, health hints. Uploading a user-behavior log to a free converter website means handing a stranger the most sensitive artifact most companies produce, for a conversion you can do in a browser tab in two seconds.
So the architecture is the privacy policy here, stated in wiring rather than in a document: the file is read by local JavaScript, flattened in memory, and written back out by your own browser's download machinery. No upload endpoint exists on this page — not for members, not for large files, not for premium. For teams under GDPR or HIPAA scrutiny, that's not a feature; it's the difference between a tool you can use and one you legally shouldn't.
Straight questions about line-delimited JSON
What's the difference between JSONL, NDJSON, and JSON Lines?
Nothing but the name — all three describe the same format: one complete JSON object per line, with lines separated by ordinary newline characters. JSON Lines is the fuller name, NDJSON (newline-delimited JSON) is the engineering slang, and .jsonl is the file extension. The tool accepts all of them, along with the \n-delimited exports of most logging and ML pipelines.
Can it convert a regular .json file that's just one big array?
Yes. The tool detects the two shapes JSON exports come in — one-object-per-line, or a single pretty-printed array — and routes accordingly. If your file starts with an opening bracket and contains thousands of lines, it's an array; if every line starts with an opening brace, it's JSONL. Both land in the same CSV.
What happens to nested objects and arrays inside my records?
Nested objects are flattened to dot-path columns — user.name becomes a column called user.name, and user.address.city becomes user.address.city. Arrays are serialized as compact JSON in their cell by default, or can be dropped entirely with one toggle. Depth is unlimited; the column name just gets longer.
My records have different keys in different lines. Will that break the CSV?
No — that's normal for event logs, and the standard handling is a union of headers: the CSV gets one column for every key that appears in any record, and cells for keys a record doesn't have are simply empty. The tool also reports which columns are sparse, so you can prune fields that appear in a fraction of a percent of lines.
Will commas and quotation marks in my data corrupt the CSV?
No, as long as the writer follows RFC 4180, which this one does: any field containing a comma, a quote, or a line break gets wrapped in double quotes, and a literal double quote inside the data is written twice — "" — which every serious CSV reader parses back as one quote character. Hand-rolled string concatenation is what corrupts CSV; quoting rules are what prevent it.
Why does Excel show my CSV in one column or with broken characters?
Two legacy quirks, both handled here. Excel assumes the local list separator — a comma in the US, a semicolon in much of Europe — so the tool can write either delimiter. And Excel guesses encodings badly, so a UTF-8 BOM is prepended by default to make accented characters and non-Latin scripts display correctly. Both settings live on the export panel.
Is there a file size limit?
Nothing server-side, because nothing uploads. The file is read and parsed in your browser, so the practical ceiling is memory: files around 100 MB convert comfortably on a normal laptop, and the reader processes line by line rather than loading everything at once. A 2.4 MB event log finishes in about two seconds.
Does my data get uploaded anywhere?
No. Parsing, flattening, and CSV writing all run locally in JavaScript, and the download is generated in your browser from memory. Log files and model datasets tend to contain personal data, which is precisely why this tool was built to never transmit them.
The format-family workbench
Every direction of the JSON-family traffic is covered nearby: JSON to CSV for document files, Nested JSON to CSV for deep trees, JSONLines to JSON to pretty-print the whole array, and CSV to JSONL for the ride back when a spreadsheet edit has to rejoin a pipeline. One bookmark, no uploads, and the curly-brace wall stops being a wall.
Sources and further reading
- JSON Lines — the official format specification — https://jsonlines.org/
- NDJSON — newline-delimited JSON specification — http://ndjson.org/
- IETF — RFC 7464: JSON Text Sequences — https://www.rfc-editor.org/rfc/rfc7464.html
- IETF — RFC 4180: CSV format and quoting rules — https://www.rfc-editor.org/rfc/rfc4180.html
- MDN Web Docs — JSON.parse() — https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
We cite primary sources (standards bodies, government agencies, official documentation) wherever they exist so you can verify every number on this page yourself.