Skip to content
Morphr

JSON vs CSV: Nested Data or a Flat Table?

By Andrew Butson · July 2, 2026 · 8 min read

Use CSV when your data is genuinely tabular: every record has the same flat set of fields, and it's headed for a spreadsheet or a simple database table. Use JSON when records nest, such as an order with a list of line items or a user with an array of addresses, or when the data is going straight into an API or a program that already speaks JSON natively. Converting JSON to CSV doesn't fail so much as it flattens: nested structure gets squashed into columns, and that squashing is a one-way trip you should only take once you know the shape you're flattening into is the one you actually want.

JSON and CSV solve the same basic problem, moving structured data between programs, with opposite assumptions about shape. CSV assumes your data is already a table: one row per record, one column per field, nothing nested inside anything else. JSON assumes nothing of the sort. An object can hold another object, which can hold an array of further objects, as deep as the data actually needs to go, because JSON's whole design is built around arbitrary nesting rather than a fixed grid.

That difference decides almost everything else here: which format actually fits your data without distortion, what a converter has to do to bridge the two, and why a third format, JSON Lines, exists specifically to borrow CSV's streaming-friendly shape without giving up JSON's nesting.

JSON vs CSV at a glance
JSON CSV
Structure Nested objects and arrays, any depth Flat rows and columns only
Types Strings, numbers, booleans, null None — everything is text
Native fit JavaScript, REST APIs, most programming languages Spreadsheets, databases, data-analysis tools
Streaming a large file Awkward — a single array must be read whole Natural — read and process one row at a time
Comments allowed No No
Schema built in No (JSON Schema is a separate, optional spec) No
Per-record size overhead Higher — key names repeat in every object Lower — column names are stored once, in the header
Middle path for large datasets JSON Lines (JSONL/NDJSON) — one record per line n/a — CSV already streams by row

Nested objects vs a flat grid

JSON represents data as key/value objects and ordered arrays, nested as deeply as the data needs: an object can be a value inside another object, and an array can hold a list of further objects, so a single JSON document can model a customer with several addresses, each address with several fields, without contorting anything. That flexibility is why JSON is the default shape for API responses and application state: real-world data is very often hierarchical, and JSON just represents it as it is.

CSV can't do any of that. A CSV file is strictly rows and columns: one record per row, one value per column, and nothing inside a cell but a single flat value. There's no way to put a list of three phone numbers into one cell without inventing your own convention (semicolon-separated, say), and there's no way to represent a customer with a variable number of addresses without either padding every row to the maximum or losing the extra ones. CSV isn't a lesser format for this; it simply assumes a shape of data (uniform, flat, one-record-per-row) that a lot of real data genuinely has, and handles that shape with far less overhead than JSON does.

What flattening JSON into CSV actually does

Converting JSON to CSV isn't a neutral repackaging. It's a real transformation with real consequences. Morphr reads your JSON records and maps each one to a row, taking the field names as columns; where a field is itself nested, it gets flattened into the row rather than dropped, but the process necessarily discards the tree structure that let a field be arbitrarily deep. A record with a variable number of sub-items, or fields that only exist on some records, either produces ragged rows or extra columns most rows leave empty. CSV has to force a fixed set of columns onto data that JSON never required to have one.

The trip back is not automatically symmetrical, either. Converting CSV to JSON turns each row into a flat object keyed by the header row and wraps the set in an array, a faithful, lossless step, because CSV had no nesting to begin with. But that's only a mirror of a CSV file that started flat; it doesn't reconstruct whatever hierarchy a different JSON document might have had before someone flattened it into CSV in the first place. Flattening is the lossy direction; unflattening only gets you back to a flat object, not to whatever nested shape existed further upstream.

Deciding whether your data is actually tabular

The practical test is simple: if every record has the same fields, one level deep, with no field that's itself a list of several things, your data is already tabular and CSV is a natural, efficient fit: you lose nothing by using it and gain a format every spreadsheet and database understands. The moment a record can have a variable number of something (multiple line items on an order, multiple tags on a post, an arbitrary-depth comment thread), you're dealing with hierarchical data, and forcing it into CSV means inventing a lossy convention for the parts that don't fit a single cell. JSON has no such ceiling, because nesting is part of the format rather than a workaround bolted onto it.

Streaming, size, and the JSON Lines middle path

Size and streaming favour CSV for genuinely tabular data: column names are written once, in the header, while a JSON array of objects repeats every key name in every record, which adds real overhead at scale. CSV also streams naturally, since a program can read and act on one row at a time without waiting for the rest of the file, whereas a single large JSON document is technically one value, and a strict parser can't fully trust anything inside it until it reaches the closing bracket at the end.

JSON Lines (JSONL, also called NDJSON) exists to close that gap without giving up nesting. It puts one complete JSON object on each line, with no surrounding array and no trailing commas between records, so a program can read, parse and process one line (one full record, nested fields and all) at a time, then move to the next. That gives it CSV's practical streaming and append-friendly behaviour (adding a record is just writing another line, and a corrupted line damages one record rather than the whole file) while keeping JSON's ability to nest data inside each record. It's why JSONL is the standard shape for logs, large dataset exports and machine-learning training data. Morphr converts between JSON, JSONL and CSV/TSV directly, so gathering JSONL into one JSON array, splitting JSON into JSONL, or flattening either into CSV columns is a single conversion rather than a script you have to write yourself.

Reach for JSON when…

  • Records nest — line items, addresses, tags, or any list-within-a-record.
  • The data is going straight into an API, a JavaScript app, or code that already parses JSON.
  • Different records can legitimately have different fields.
  • You are working with configuration or application state rather than a dataset for analysis.
  • The dataset is large and gets processed a record at a time, so pair with JSON Lines rather than one giant array.

Reach for CSV when…

  • Every record has the same flat set of fields — genuinely tabular data.
  • The destination is a spreadsheet, a simple database table, or an analysis tool.
  • You want the smallest, most streaming-friendly form of a large flat dataset.
  • A colleague or tool needs to open and read the data without writing any code.
  • You need to diff or track changes to the data as plain text.
Convert JSON to CSV — free, in your browser

Flattens your JSON records into rows and columns entirely on your device, with nothing uploaded.

Runs entirely in your browser — nothing is uploaded.

Frequently asked questions

What happens to nested JSON fields when I convert to CSV?
They get flattened into the row rather than dropped. But the tree structure is lost in the process, since a CSV cell can only hold one flat value. If your JSON has fields that vary in shape or number between records, expect either extra columns that are empty for most rows, or a lossy convention for anything CSV genuinely can't represent in a single cell.
Can I convert a CSV back into properly nested JSON?
Converting CSV to JSON turns each row into a flat object keyed by the header row, a faithful conversion, since CSV never had any nesting to begin with. It reconstructs the flat shape the CSV actually holds, not a hierarchy that might have existed in some earlier JSON document before it was flattened.
What is JSON Lines and when should I use it instead of JSON or CSV?
JSON Lines (JSONL/NDJSON) puts one complete JSON object per line instead of wrapping everything in a single array. It streams and appends the way CSV does, while still letting each record nest the way JSON does, which is why it is the standard choice for logs, large exports and machine-learning datasets rather than a single monolithic JSON file.
Which is smaller, JSON or CSV, for the same data?
For genuinely flat, uniform data, CSV is usually smaller, because column names are written once in the header rather than repeated as a key in every object the way a JSON array does. JSON's overhead buys you the ability to represent nested and variable-shape data that CSV structurally cannot hold at all.