How to convert ndjson / json lines to csv
- Step 1Get your NDJSON / JSONL file — This is any file with one JSON object per line and no surrounding array —
.ndjson,.jsonl,.json, or.txtall work. Drop it onto the converter above. Free files cap at 2 MB. - Step 2Set the input format to NDJSON / JSONL — Selecting it explicitly avoids any ambiguity. Auto detect also works — it parses as whole-document JSON first and falls back to line-by-line NDJSON when that fails.
- Step 3Keep Flatten nested objects on — Structured log events usually nest a payload object. Flattening turns
event.user.idinto its own column. Turn it off to keep each event payload as a JSON string in one cell. - Step 4Choose array handling — Log records often carry arrays (
tags,args). Pick JSON literal to keep them re-parseable, or Pipe / Comma joined for readable cells. - Step 5Convert and read the line count — Click Convert to CSV. Records in should equal the number of non-empty lines in your file. If a line is malformed, the error names it — fix that line and re-run.
- Step 6Download for your destination — Excel-Ready CSV (BOM + CRLF) for spreadsheets and BI tools; plain Download CSV (LF) for grep / awk / Python pipelines.
NDJSON parsing behaviour
How the converter treats line-delimited input. Blank lines are ignored.
| Situation | Behaviour |
|---|---|
| One object per line | Each non-empty line becomes one CSV row |
| Blank / whitespace lines | Skipped — they do not produce empty rows |
| Ragged records (different keys per line) | Union header; missing fields become empty cells |
| A line that is not valid JSON | Conversion aborts with Invalid JSON on line N |
First line starts with { (Auto detect) | Whole-document parse fails, then NDJSON fallback succeeds |
Auto detect vs explicit NDJSON
When to force the NDJSON format instead of relying on Auto detect.
| Input format | What it does | Best for |
|---|---|---|
| Auto detect | Tries JSON, falls back to NDJSON on failure | Mixed pipelines where the file could be either |
| NDJSON / JSONL | Always parses line-by-line | Known log / stream exports — most reliable |
| JSON array | Parses the whole file as one array | Files that are genuinely [ {...} ], not line-delimited |
Cookbook
Real NDJSON log snippets and the CSV the converter produces.
Structured application log to CSV
ExampleEach log line is one JSON object. Nested context flattens to dot-notation columns.
Input (app.ndjson):
{"ts":"2026-06-01T10:00Z","level":"info","ctx":{"user":42}}
{"ts":"2026-06-01T10:01Z","level":"error","ctx":{"user":7},"err":"timeout"}
Output CSV:
ts,level,ctx.user,err
2026-06-01T10:00Z,info,42,
2026-06-01T10:01Z,error,7,timeoutRagged records aligned by union header
ExampleOnly the error line has an err field; the union header keeps everything in a single aligned column.
Input:
{"id":1,"ok":true}
{"id":2,"ok":false,"err":"429"}
Output CSV:
id,ok,err
1,true,
2,false,429Pinpointing a malformed line
ExampleA truncated write left line 2 invalid. The error names the line so you can fix exactly one record.
Input:
{"id":1}
{"id":2, <-- truncated, no closing brace
{"id":3}
Result:
Error: Invalid JSON on line 2 — Unexpected end of JSON input
Fix line 2, then re-run.Array of args joined for readability
ExampleA command-log line carries an args array; comma-joining makes it readable in a spreadsheet cell.
Input:
{"cmd":"deploy","args":["--env","prod"]}
Array values = Comma joined:
cmd,args
deploy,"--env, prod"NDJSON that starts with a brace, via Auto detect
ExampleBecause the first line is a complete object, naive parsers think the file is a single JSON document. Auto detect tries that, fails on line 2, and falls back to NDJSON automatically.
Input (Auto detect):
{"a":1}
{"a":2}
Whole-document JSON parse fails after line 1 →
NDJSON fallback succeeds →
Output CSV:
a
1
2Errors and edge cases
Real errors and silent failures sourced from each platform's own documentation. Match the wording to the row, fix what the row says to fix.
Trailing blank line at end of file
SupportedBlank and whitespace-only lines are filtered out before parsing, so a trailing newline does not create an empty trailing row.
A single malformed line
Invalid JSONOne bad line aborts the whole conversion with Invalid JSON on line N. NDJSON has no partial-success mode here — remove or repair the named line and re-run.
File is actually a JSON array, not NDJSON
SupportedIf you forced NDJSON / JSONL on a [ {...}, {...} ] array, the first line [ is not valid standalone JSON and it errors. Switch to Auto detect or JSON array for array files.
Pretty-printed JSON objects split across lines
Invalid JSONNDJSON requires each object to occupy exactly one line. A pretty-printed object spanning multiple lines breaks line-by-line parsing. Minify it first with json-minifier, or treat the file as a JSON array if it is one.
Very large log file over 2 MB
BlockedFree conversions cap at 2 MB / 500 rows. For large log dumps, upgrade to Pro (100 MB / 100,000 rows) or split the file with split -l.
Records with deeply nested event payloads
ExpectedDeep payloads flatten to many dot-notation columns. That can make a wide CSV — prune with json-key-filter first if you only need a few fields.
Arrays inside log records
Not expandedArrays land in one cell, not extra rows. Extract an array path with json-path-extractor if you need one row per array element.
Empty file
ExpectedAn empty or whitespace-only file yields zero rows and an empty CSV, with no error.
Frequently asked questions
What is the difference between NDJSON, JSONL, and JSON Lines?
They are three names for the same format: one complete JSON object per line, no surrounding array, no inter-record commas. This tool handles all of them identically.
Should I use Auto detect or force NDJSON?
Forcing NDJSON / JSONL is most reliable for known log exports. Auto detect also works — it tries whole-document JSON and falls back to NDJSON even when the first line starts with {.
What happens if one line is malformed?
Conversion stops with Invalid JSON on line N, naming the exact bad line. NDJSON parsing is all-or-nothing here, so fix or remove that line and re-run.
Are blank lines a problem?
No. Blank and whitespace-only lines are skipped before parsing, so they never become empty rows.
Will ragged records (different keys per line) align?
Yes. The header is the union of all keys across every line, so each record's values land in the right columns with empties where a field is absent.
Do nested fields in each line get flattened?
Yes, with Flatten nested objects on (default). event.user.id becomes its own column. Turn it off to keep each payload as a single JSON-string cell.
My objects are pretty-printed across multiple lines — will it work?
Not as NDJSON, which needs one object per line. Minify first with json-minifier, or if the file is actually a JSON array, use the JSON array input format.
How big a log file can I convert?
Free: 2 MB / 500 rows. Pro: 100 MB / 100,000 rows. Split large dumps with split -l if needed.
Is my log data sent to a server?
No. Parsing and conversion happen in your browser. Logs — which can contain user identifiers — never upload to JAD Apps.
How are arrays in log records handled?
They go into one cell (JSON literal, pipe, or comma). Arrays are not expanded into rows — extract the path with json-path-extractor for that.
Can I convert CSV back to NDJSON?
Yes — csv-to-json can produce line-delimited JSON output suited to streaming systems and mongoimport.
Why CRLF in the Excel-Ready download?
Excel on Windows expects CRLF line endings and a UTF-8 BOM. The Excel-Ready CSV adds both; the plain Download CSV uses LF for code pipelines.
Privacy first
Conversion runs locally in your browser. No file is uploaded — only metadata counters are saved for signed-in dashboard stats.