converters · · Updated

How to Flatten Nested JSON and Convert JSONL Files

By

A spreadsheet is a flat grid, and most real JSON isn't flat. Customers have addresses, orders have line items, and log events carry nested context. Flattening is how the two meet: every nested value gets its own column, named by the path to it. This guide shows exactly what that produces, what comes back when you reverse it, and how JSON Lines files fit in.

Flattening, with a real example

Two orders, with nesting at three levels and arrays of different lengths:

[
  { "id": 1, "customer": { "name": "Asha", "address": { "city": "Pune" } },
    "tags": ["new"], "items": [{ "sku": "A1", "qty": 2 }] },
  { "id": 2, "customer": { "name": "Ravi", "address": { "city": "Surat" } },
    "tags": ["vip", "repeat"], "items": [] }
]

Flattened to CSV:

id,customer.name,customer.address.city,tags.0,items.0.sku,items.0.qty,tags.1,items
1,Asha,Pune,new,A1,2,,
2,Ravi,Surat,vip,,,repeat,

The rules behind that output:

  • Objects join their keys with dots: customer.address.city.
  • Arrays use the position as a key: tags.0, tags.1, and items.0.sku for a field inside the first array item.
  • Columns are the union across all records, in the order they first appear. tags.1 exists only because Ravi has a second tag, and it still gets a column. Asha's cell there is simply empty.
  • An empty array or object gets a column of its own name (items) with an empty value, so the record doesn't vanish from the table.

Watch the column count

Positional columns grow with your longest array. One record with 40 line items produces items.0.sku through items.39.qty, which is 80 columns, and every other record has 80 mostly empty cells. That's fine for inspecting data. If what you actually want is one row per line item (to total quantities, say), flattening is the wrong shape. Extract the items arrays into their own list first, then convert that.

Rebuilding the nested JSON

The reverse direction reads the dotted headers and rebuilds the structure. Numbered path segments that start at 0 become arrays again; other numeric keys, such as years, stay object keys. For the CSV above, the first order comes back exactly as it started. The second comes back identical except for one field:

{ "id": 2, "customer": { "name": "Ravi", "address": { "city": "Surat" } },
  "tags": ["vip", "repeat"], "items": "" }

That's the one thing a flat table can't express: an empty array and a missing value look the same, so "items": [] comes back as an empty string. Three more details matter if you edit the sheet before converting back:

  • Empty cells in numbered columns are skipped. Asha's blank tags.1 doesn't turn into ["new", null]. Her array stays one item long.
  • Values are typed on the way back. 2 becomes a number and true a boolean, but codes with a leading zero, like 004102, stay strings.
  • Dots in your original keys are ambiguous. A key literally named "version.major" is indistinguishable from a nested version → major path, so it comes back nested. Rename such keys before flattening if the round trip matters.

The Nested JSON ⇄ CSV (Flatten) tool does both directions for CSV. Nested JSON ⇄ Excel (Flatten) does the same with a .xlsx file, which is easier to hand to someone who'll edit it in Excel and send it back. If your JSON has no nesting at all, the plain JSON ⇄ CSV Converter gives the same result. It writes any nested values it does meet as JSON text in a single cell rather than splitting them into columns.

What JSON Lines is

A JSON Lines (JSONL, or NDJSON) file puts one complete JSON value on each line, with no surrounding array and no commas between records:

{"ts":"2026-09-24T10:02:11Z","level":"info","msg":"login","user":"u_81"}
{"ts":"2026-09-24T10:02:15Z","level":"error","msg":"payment failed","user":"u_81","code":"CARD_DECLINED"}

Logging pipelines, database exports, and machine-learning datasets use it because a program can append one line at a time, and read one line at a time without loading the whole file. The flip side is that a JSONL file is not valid JSON, so a normal JSON parser rejects it.

Each record must fit on one line. Pretty-printed JSON, with an object spread across several lines, isn't JSONL. In the file below, lines 3 to 5 hold one object, so the converter stops with Invalid JSON on line 3:

{"a":1}

{
  "b": 2
}

Blank lines are skipped. The line numbers in error messages still count them, so the number matches what your text editor shows.

Converting JSONL

  • JSONL ⇄ JSON wraps the lines into a standard JSON array, or splits an array back into lines. Use it to feed a log export to a tool that expects ordinary JSON.
  • JSONL ⇄ CSV creates a column for every field that appears on any line. In the log above, code only exists on the error event, and it still gets a column. Log formats add optional fields constantly, so a converter that took its columns from the first line would silently drop them.
  • JSONL ⇄ Excel goes straight to a spreadsheet, subject to Excel's 1,048,576-row limit per sheet.

If the JSONL records are themselves nested, convert to JSON first, then flatten. All of these tools run in the browser and accept files up to 200MB, so a log file containing user IDs never leaves your machine.

Related guides