Skip to content

What Is NDJSON? Newline-Delimited JSON Explained

Sep 9, 2026 · Formats & Standards

NDJSON (newline-delimited JSON) is a text format where each line is a separate, complete JSON value, and lines are separated by the newline character; it is designed to stream or store many JSON records without wrapping them in a single array. Because each record stands alone on its own line, a program can read, write, and process records one at a time instead of loading an entire document into memory. This makes NDJSON the natural choice for logs, event streams, bulk data exports, and large datasets that would be impractical to hold as one giant JSON array.

Key takeaways

  • Each line of NDJSON is an independent, valid JSON value, almost always a JSON object.
  • Records are separated by a line feed (n); the file as a whole is not a single JSON document.
  • The de facto media type is application/x-ndjson, and JSON Lines (.jsonl) is the same idea.
  • NDJSON streams and appends efficiently, which a plain JSON array cannot do without rewriting the whole structure.
  • Parse it by splitting on newlines and decoding each line separately; never parse the whole stream at once.
  • Records must be UTF-8 and must not contain unescaped raw newlines, which JSON already forbids inside values.

What does NDJSON look like?

An NDJSON document is just JSON values stacked line by line. There are no enclosing brackets and no commas between records.

{"id":1,"name":"Ada","active":true}
{"id":2,"name":"Linus","active":false}
{"id":3,"name":"Grace","active":true}

Each line is self-contained: you could take any single line, hand it to a standard JSON parser, and get a valid object. That property is the whole point, and it is what separates NDJSON from a conventional JSON array.

How is NDJSON different from a JSON array?

A JSON array packages every element inside one document, so a consumer must read the closing bracket before it can be sure the document is complete and valid. NDJSON removes that outer structure, trading a single self-describing document for a stream of independent records.

Aspect JSON array NDJSON
Overall structure One document: [ ... ] Many documents, one per line
Separators Commas between elements Newlines between records
Streaming reads Hard; usually needs the whole document Easy; process line by line
Appending a record Must edit inside the closing bracket Just write another line
Partial file validity A truncated file is invalid Complete lines remain valid
Memory footprint Proportional to full dataset Proportional to one record

Why do developers use NDJSON?

NDJSON earns its place wherever data arrives or grows over time:

  • Logging and events: each event is appended as one line, so writers never rewrite earlier data and readers can tail the file.
  • Streaming APIs: a server can flush one record at a time, letting the client start work before the response finishes.
  • Bulk import and export: databases and search engines accept NDJSON so they can ingest millions of records without buffering an entire array.
  • Data pipelines: line-oriented tools compose naturally with NDJSON because each line is a unit of work.

The unifying benefit is bounded memory: you process one record, discard it, and move to the next, regardless of how large the overall stream is.

What is the correct media type and file extension?

Over HTTP, NDJSON is commonly served with the media type application/x-ndjson. On disk it typically uses the extension .ndjson, while the closely related JSON Lines convention uses .jsonl. There is also a distinct but related IETF standard, JSON Text Sequences (RFC 7464, media type application/json-seq), which separates records with a record-separator control character rather than a plain newline; it is not byte-identical to NDJSON, so do not assume the two are interchangeable at the byte level.

How do I parse NDJSON correctly?

The core algorithm is simple: read the stream, break it at newline boundaries, and decode each non-empty line with an ordinary JSON parser.

for each line in stream split on "n":
  trimmed = line without trailing r and surrounding spaces
  if trimmed is empty: continue
  record = jsonParse(trimmed)
  handle(record)

For true streaming you should not split the whole input at once, because that defeats the memory advantage. Instead, buffer incoming bytes, emit a record each time you encounter a newline, and keep any partial trailing line in the buffer until more data arrives.

Common mistakes to avoid

  1. Parsing the whole file as one JSON value. It is not a single document and will fail immediately.
  2. Assuming a trailing newline or none. Tolerate both a final empty line and its absence.
  3. Ignoring carriage returns. Files created on some platforms use rn; strip a trailing r defensively.
  4. Emitting pretty-printed JSON. Records must be single-line, so serialize each record compactly with no embedded literal newlines.

What are the encoding and safety considerations?

NDJSON must be UTF-8, matching JSON’s own requirement, and each record must be compact JSON on exactly one physical line. This works because JSON never allows a raw, unescaped newline inside a string; any newline in your data is stored as the two-character escape n, so it cannot be mistaken for a record separator.

From a safety standpoint, treat each line as untrusted input and validate it independently. A malformed line should not crash the whole pipeline: decide up front whether to skip it, log it, or fail, and enforce a maximum line length so a single pathological record cannot exhaust memory. Because records are independent, a corrupt or truncated final line can be discarded without invalidating everything read before it, which is a resilience advantage over a single large array.

When should I not use NDJSON?

NDJSON is a poor fit when you need one self-describing document that carries top-level metadata alongside the records, or when consumers expect a single JSON value they can validate as a whole against a schema. It also offers no benefit for small, fixed payloads where a plain array is simpler for callers to consume. Reach for NDJSON specifically when the dataset is large, unbounded, or produced incrementally.

Frequently asked questions

Is NDJSON the same as JSON Lines?

In practice yes. JSON Lines (JSONL) and NDJSON both put one JSON value per line separated by newlines; they describe essentially the same format and are widely treated as interchangeable.

What media type should NDJSON use?

The commonly used type is application/x-ndjson. Some tools also accept application/jsonlines or application/json-seq for the related RFC 7464 sequence format.

Can an NDJSON file contain a top-level array?

No. Each line is its own independent JSON value, usually an object. The file as a whole is not a single JSON document and will not parse as one array.

Which newline separates NDJSON records?

A line feed (LF, n) separates records. Tools should tolerate a trailing newline and, defensively, a carriage return before the LF.

Do newlines inside a record break NDJSON?

No, because JSON encodes literal newlines inside strings as the escape n, so a single record never contains a raw line break. Only the separators between records are real newlines.

Why use NDJSON instead of a JSON array?

NDJSON can be produced, transmitted, and consumed one record at a time without loading everything into memory, and you can append new records by writing another line.

How do I parse NDJSON?

Split the stream on newlines and run a standard JSON parser on each non-empty line. Never try to parse the whole file as one JSON document.

Frequently asked questions

Is NDJSON the same as JSON Lines?

In practice yes. JSON Lines (JSONL) and NDJSON both put one JSON value per line separated by newlines; they describe essentially the same format and are widely treated as interchangeable.

What media type should NDJSON use?

The commonly used type is application/x-ndjson. Some tools also accept application/jsonlines or application/json-seq for the related RFC 7464 sequence format.

Can an NDJSON file contain a top-level array?

No. Each line is its own independent JSON value, usually an object. The file as a whole is not a single JSON document and will not parse as one array.

Which newline separates NDJSON records?

A line feed (LF, \n) separates records. Tools should tolerate a trailing newline and, defensively, a carriage return before the LF.

Do newlines inside a record break NDJSON?

No, because JSON encodes literal newlines inside strings as the escape \n, so a single record never contains a raw line break. Only the separators between records are real newlines.

Why use NDJSON instead of a JSON array?

NDJSON can be produced, transmitted, and consumed one record at a time without loading everything into memory, and you can append new records by writing another line.

How do I parse NDJSON?

Split the stream on newlines and run a standard JSON parser on each non-empty line. Never try to parse the whole file as one JSON document.

Contact: contact@quikconsolecom.net