NDJSON CSV Converter
BetaConvert NDJSON (JSONL) to CSV or CSV to NDJSON on one page. Nested keys flatten to dot paths, bad lines are named, and types coerce on request.
- Free, no sign-up
- REST + MCP
- Updated
- Reviewed by Olgun Ozoktas
Converted in your browser. This page does not upload the file. NDJSON to CSV flattens nested keys to dot paths, and null and a missing key both become an empty cell. CSV to NDJSON uses the header row as the keys and does not rebuild nested objects from dotted names. A huge file is limited by tab memory, so use Download, not Copy, for a big output.
The flat CSV will appear here..
How to Convert NDJSON to CSV and CSV to NDJSON Online
-
Pick the direction at the top of the tool
NDJSON to CSV or CSV to NDJSON. Switching moves the current output into the input, so a round trip takes one click. -
Drop the .ndjson, .jsonl or .csv file on the input panel, upload it, or paste the text
The conversion runs as soon as the text arrives. -
For NDJSON to CSV, choose how nested values are written
Flatten turns user.name and tags[0] into their own columns; JSON cell keeps a nested object or array as JSON text in one cell. Pick the separator your reader expects, and turn on Excel BOM if Excel shows accented characters wrongly. -
For CSV to NDJSON, leave Header row on so the first row becomes the keys
The separator is detected from the header line. Turn on Coerce types only when the loader expects numbers and booleans; off, 007 and a phone number stay intact as strings. -
Read the status line and the notes
rows, columns, skipped lines and renamed keys. Then download the result or copy it.
Common Use Cases
Open an API request log in Excel or Google Sheets and filter by status, path or user
Turn an Elasticsearch or OpenSearch hits dump into rows a report can count
Check a fine-tune .jsonl file in a spreadsheet before you train on it
Load a streaming export into a warehouse or a BI tool that reads CSV
Share a slice of log data with someone who has a spreadsheet and no shell
Turn a product sheet into the record-per-line file a bulk loader reads
Build a prompt and completion dataset for a fine-tune job from a spreadsheet
Feed a contacts or events export into a pipeline that reads JSON Lines
Why Use Our NDJSON CSV Converter?
JSON Lines is a text format with one JSON value per line, separated by line feeds. Log shippers, streaming exports and machine-learning datasets use it because a writer can append one record at a time and a reader can process one line at a time without loading the whole file. The trade-off is that the file as a whole is not valid JSON, so a converter that calls JSON.parse on the text fails on the second line. This page converts JSON Lines to CSV and CSV back to JSON Lines, and parses each line on its own.
NDJSON to CSV writes one CSV row per JSON object. The header is built from every key in every row, in first-seen order, so a key that appears only on line 900 still gets a column and earlier rows get an empty cell there. With Flatten, the default, a nested object becomes dot paths such as user.name and user.city, and an array becomes indexed keys such as tags[0] and tags[1], recursively. With JSON cell, a nested object or array is written as JSON text in one cell, quoted as CSV requires. null and a missing key both write an empty cell; numbers and booleans are written as text. A line that is not valid JSON, or that is JSON but not an object, is skipped, counted, and listed as Line N with its file line number, and the other lines still convert.
CSV to NDJSON reads the CSV per RFC 4180 and writes one JSON object per line, in header order, with LF line ends. The header row becomes the keys: names are trimmed, an empty name becomes column_N, and a duplicate name gets a numeric suffix so no value is lost. The separator is detected from the header among comma, semicolon, tab and pipe, or set by hand. Every value is a string by default, because a CSV has no types and a wrong guess corrupts data silently. With Coerce types on, true and false become booleans, null and an empty cell become null, and a plain number becomes a JSON number; a number with leading zeros stays text, and an integer of 2^53 or more stays text so a 64-bit id keeps every digit. Dotted header names are not rebuilt into nested objects.
In both directions a leading byte order mark is dropped, CRLF line ends are accepted, blank lines are skipped, and quoting follows RFC 4180. The input cap is 10 MB. On this page nothing is uploaded: both directions run in your browser.
How it compares
A jq or Python one-liner, or a pandas script, does the same job on a workstation with those tools installed and someone to write the flatten step and the type rules. Online converters that upload the file hand a log of your users' requests, or a customer list, to a server for a format change. This page reads JSON Lines with its line rule and CSV per RFC 4180, builds a stable header from every row, makes the type decision one explicit switch, names the lines it skipped and the keys it renamed, and keeps the file in the tab.
NDJSON and CSV Conversion Tips
- The header is the union of every key across every line, in the order the keys first appear. A key that a row does not have is an empty cell, and so is null.
- Under Flatten, an array becomes indexed columns: tags[0], tags[1]. A row with five tags creates five columns. Use JSON cell when you want the whole array in one cell.
- An empty object or an empty array produces no column under Flatten. If a field is empty on every row, it does not appear.
- Numbers and booleans are written as text, so 1.5 and true look the same in the CSV as in the JSON. The spreadsheet decides the type when it opens the file.
- A file that starts with [ is a JSON array, not JSON Lines. The page refuses it and links to the JSON to CSV tool, which reads arrays.
- Coerce types turns true and false into booleans, null and an empty cell into JSON null, and a plain number into a JSON number. 007 stays the string 007, and an integer of 2^53 or more stays a string so no digit is lost.
- Dotted header names such as user.name stay flat keys. The tool does not rebuild nested objects, so the key in the JSON is the text user.name.
- An empty header cell becomes column_N. A duplicate header gets a suffix: the second a is a_2. The notes say which names changed.
- A row with more values than the header keeps the first values and is named in the notes with its row number. The header is row 1.
- The output has LF line ends and one trailing newline. .ndjson and .jsonl are the same format under two names.