If you’ve spent any time working with APIs or data files, you’ve probably run into JSON. It’s everywhere. But NDJSON? That one might not sound so familiar. Here’s what both formats are, how they differ, and when one makes more sense than the other.
What Is JSON?
JSON stands for JavaScript Object Notation. It’s a lightweight format for storing and transporting data, and it’s become the default language that web services use to talk to each other.
A JSON file holds data as a single, structured object or array. Everything is wrapped up together, like this:
[
{ "id": 1, "name": "Priya", "role": "admin" },
{ "id": 2, "name": "Marcus", "role": "editor" },
{ "id": 3, "name": "Yuki", "role": "viewer" }
]
The whole thing is one valid JSON document. Your parser reads it from start to finish, and you get your data.
That works great for most situations. But it can start to cause problems when your data gets really big.
What Is NDJSON?
NDJSON stands for Newline Delimited JSON. Instead of wrapping everything in a single structure, each line is its own self-contained JSON object.
The same data from above would look like this in NDJSON:
{ "id": 1, "name": "Priya", "role": "admin" }
{ "id": 2, "name": "Marcus", "role": "editor" }
{ "id": 3, "name": "Yuki", "role": "viewer" }
At first glance, you might not notice any difference. But when you look closely, you’ll notice that this one is missing a few things. This NDJSON block contains three separate JSON objects. No surrounding array, no commas between records. Just one object per line.
It’s a simple idea, but it can be surprisingly useful.
The Main Problem with Large JSON Files
Imagine you have a log file with 10 million records. In standard JSON, that’s one enormous array. To read it, your program has to load the entire file into memory, parse the whole thing, and only then can you start doing anything with the data.
That’s expensive. Slow to read, heavy on memory, and a real pain if something goes wrong halfway through parsing.
NDJSON sidesteps this completely. Because each line is independent, you can read and process one record at a time. You don’t need to hold the whole file in memory. You just work through it line by line, which is much more efficient for large datasets.
Main Differences Between JSON and NDJSON
Despite their similarities, there are some important differences that will influence your decision on which one to use for a given situation:
| JSON | NDJSON | |
|---|---|---|
| Structure | One complete document | One JSON object per line |
| Memory usage | Loads everything at once | Read line by line, low memory footprint |
| Streaming | Possible, but requires a specialist streaming parser | Works with any basic line reader, no special tooling needed |
| Error handling | One bad record breaks the whole file | Bad records can be skipped individually |
| Appending data | Requires editing the file structure | Just add a new line |
The streaming part is worth unpacking. Streaming JSON is technically possible using specialist parsers that work through a document incrementally rather than loading it all at once, but it adds complexity and is not the default behaviour of most JSON libraries. NDJSON makes streaming straightforward by design. Because every line is a complete, self-contained object, any tool that can read a file line by line can start processing records as they arrive, without needing to wait for the full file or reach for special parsing logic.
When to Use JSON
Standard JSON is the right choice for most everyday tasks. If you’re building an API response, sending configuration data, or working with datasets small enough to fit comfortably in memory, JSON is perfectly fine. It’s also easier to read at a glance, which matters when you’re debugging.
Basically, if the data is reasonably sized and you need it all at once, use JSON.
When to Use NDJSON
NDJSON is more suitable when you’re dealing with scale or real-time data. Some good use cases:
- Application logs that grow continuously over time
- Data pipelines where records are processed one at a time
- Exporting large datasets from a database
- Streaming data feeds where records arrive incrementally
- Situations where you need to append records frequently without rewriting the whole file
If you’re ever working with a file that has millions of rows, or you need to start processing data before it’s fully available, NDJSON is probably what you want.
A Quick Note on Compatibility
Most modern programming languages have libraries that support NDJSON, but it’s worth checking before you commit to the format. Standard JSON parsers won’t handle NDJSON out of the box, since the file as a whole isn’t valid JSON. You’ll need a library or a simple line-by-line reader that parses each row individually.
Tools like Python, Node.js, and most data engineering platforms handle it without much trouble.
Summary
JSON and NDJSON both store structured data, but they’re designed for different situations. JSON packages everything into one document, which is simple and works well for most use cases. NDJSON breaks data into individual lines, which makes it far better suited for large files, streaming, and scenarios where you need to process data incrementally.
If you’re not sure which to use, start with JSON. If you hit performance issues with large files, try converting it to NDJSON. However, bear in mind that while converting to NDJSON can be straightforward for flat data, it can be trickier if your records are deeply nested.