NDJSON to matrix
Paste newline-delimited JSON and get one rectangular table: nested objects flattened to dotted columns, the union of every path as the header, missing cells filled the way you choose, and CSV, TSV, an aligned grid or a JSON array of rows out.
About this tool
NDJSON (also called JSON Lines or JSONL) is great for logs and streams because each line is a complete JSON record. It is less convenient when you need a rectangular table: one record may have user.tier, the next may omit it, and nested payloads can hide the numeric columns you actually want.
This tool parses each non-blank line independently, flattens nested objects into column paths such as user.geo.lat, takes the union of every path it sees, and writes one aligned row per record. Missing paths and JSON null become your chosen fill value, so ragged event streams become CSV, TSV, a whitespace-aligned matrix, or a JSON array of rows without writing a script.
Worked example
Input:
{"id":1,"latency_ms":12,"user":{"tier":"pro"}}
{"id":2,"latency_ms":940}
{"id":3,"latency_ms":31,"user":{"tier":"free"}}
With the defaults (format=csv, headers on, first-seen columns, blank fill) the output is:
id,latency_ms,user.tier
1,12,pro
2,940,
3,31,free
Turn on Numeric columns only, set Fill for missing cells to 0, and turn headers off when you need a bare numeric matrix for numpy.loadtxt, R, Octave, or a plotting package. Use Columns to keep when you want a stable schema in a specific order.
Controls that matter
- Output format — CSV, TSV, aligned
matrix, orjsonarray-of-arrays. - Nested arrays — index arrays into columns (
reading.0,reading.1), keep the full array as JSON in one cell, or skip array-valued columns. - Column order — first seen in the stream, alphabetical for stable diffs, or coverage-first so the most-populated columns appear first.
- Max depth — cap flattening and keep deeper objects as compact JSON when a payload would explode into too many columns.
- Invalid lines — stop at the first bad line with its line number, or skip malformed lines and convert the rest.
Limits and edge cases
- Input is capped at 5,000,000 bytes, 50,000 non-blank lines, and 2,000 distinct column paths.
- JSON objects become rows keyed by flattened paths. Bare JSON arrays become positional columns
0,1,2and bare scalars go into a singlevaluecolumn. numeric_onlykeeps columns whose present values are all finite numbers; numeric-looking JSON strings count, but booleans, labels and non-finite tokens do not.- Duplicate paths inside one record keep the last value written, which can happen when path separators collide with literal key names.
- CSV output follows RFC 4180 quoting for delimiters, quotes and newlines inside cells.
FAQ
What is the difference between NDJSON and a JSON array?
NDJSON has one complete JSON value per line: {...}\n{...}\n{...}. A JSON array wraps all records in one value: [{...},{...}]. This tool expects NDJSON because that is how logs, export streams and append-only data files are usually stored. If you have one big JSON array, split it into one element per line first.
How are nested objects and arrays turned into columns?
Object keys are joined with the path separator. With the default separator, {"user":{"id":7}} becomes column user.id. Arrays default to indexed columns, so {"v":[10,20]} becomes v.0 and v.1; switch Nested arrays to JSON to keep [10,20] in one cell, or to skip to drop array-valued data entirely.
How do I make a numeric matrix with no labels?
Set Numeric columns only on, choose a fill such as 0 or NaN, and turn Include the header row off. The matrix format produces a whitespace-aligned grid, while CSV/TSV produce delimiter-separated rows that common numeric tools can load.
What happens when one line is not valid JSON?
With Unparsable lines: error, conversion stops and the error names the line number and parser location. With skip, malformed lines are ignored and the remaining records are converted. If every non-blank line is invalid, the tool still returns an error instead of emitting an empty table.
Can I force a schema instead of using every discovered column?
Yes. Put a comma-separated list in Columns to keep, such as timestamp, latency_ms, user.tier. The output uses exactly that order and fails if a requested path is absent, so typos do not silently produce empty columns.
Developer & Automation Access
Run it from the terminal
Same engine as this page, headless — via the gizza CLI:
gizza tool ndjson-to-matrix '{"id":1,"latency_ms":12,"user":{"tier":"pro"}}
{"id":2,"latency_ms":940}'New to the CLI? Get gizza →
Open it by URL
Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:
https://gizza.ai/tools/ndjson-to-matrix/?data=%7B%22id%22%3A1%2C%22latency_ms%22%3A12%2C%22user%22%3A%7B%22tier%22%3A%22pro%22%7D%7D%0A%7B%22id%22%3A2%2C%22latency_ms%22%3A940%7D&format=csv&delimiter=comma&separator=.&arrays=index&columns=latency_ms%2C%20user.tier&column_order=first-seen&fill=0&headers=true&row_index=true&numeric_only=true&transpose=true&max_depth=0&limit=0&invalid=errorMachine-readable descriptor: tool.json — title + parameters JSON Schema for agents.
