tsvkit.org
TSV Toolkit
Sample data Say hi →

JSONL to TSV

union of all keys · optional dot-notation flattening · skips bad lines

Turn newline-delimited JSON into a table you can open in a spreadsheet. Log exports, API dumps, and Kafka topic snapshots all arrive as JSONL, and JSONL is not readable — you can't scan a thousand records looking for the odd one out. Every key seen anywhere in the file becomes a column, records missing a key get an empty cell, and unparseable lines are counted and skipped rather than aborting the whole conversion.

jsonl
Drop a .jsonl file here, or
ready

How to use

  1. Paste or drop the JSONL. One JSON object per line; blank lines are ignored.
  2. Check the skipped count in the status line. It names the first line that failed, which usually explains all of them.
  3. Turn flattening off if you'd rather see nested objects as raw JSON in a single cell — sometimes that's what you want for inspection.
  4. Copy or download.

How nesting is handled

With flattening on, {"user":{"id":7,"name":"Ada"}} becomes two columns, user.id and user.name. This recurses to any depth, so a deeply nested record produces long column names but no data loss. Arrays are not flattened — {"tags":["a","b"]} becomes a single tags column containing ["a","b"] as JSON text, because expanding an array into columns would give different records different widths. To split those out afterwards, split a column on "," gets you most of the way.

Column order follows first appearance across the file, so the first record's keys set the leading columns and later-appearing keys are appended. That means a heterogeneous file — different record types on different lines — produces a wide, sparse table, which is itself useful information: it tells you the file isn't the uniform stream you assumed.

What gets lost

JSON types disappear: numbers, booleans, and null all become text, because TSV has no type system. null and "" both become an empty cell and are indistinguishable afterwards. Nested arrays become JSON strings. And a value containing a tab or newline is written as a quoted field, which needs a proper parser to read back — if the consumer is a strict tab-splitter, run the output through escape tabs and newlines.

FAQ

My file is a JSON array, not JSONL.

Use JSON → TSV, which takes an array of objects (and also accepts JSONL). This page expects one object per line and will report every line of a pretty-printed array as unparseable.

Why were some lines skipped?

Either they aren't valid JSON — a truncated last line is the usual cause on a file that was still being written — or they're valid JSON but not objects. A bare array or string on a line has no keys to become columns, so it's skipped too.

Can I select just some keys?

Convert everything, then extract columns to keep the ones you want in the order you want. For very large files jq -r '[.id, .name] | @tsv' is the leaner route.

Does the order of records change?

No — output rows are in input line order. Only the columns are reordered, and only in the sense that they're collected in first-seen order.

Privacy

100% client-side. No upload. See the privacy policy. For JSONL-specific tooling — validation, repair, splitting — see jsonlkit.com.