close

NDJSON Specification: Newline Delimited JSON Format Specification

ndjson-spec.txt

Official Specification

NDJSON uses the same newline-delimited record structure as JSONL. Each line contains one valid JSON value, most commonly an object, separated by newline characters. This page explains the NDJSON terminology and implementation rules.

NDJSON Format Rules

A valid NDJSON file must adhere to the following rules:

  1. One JSON value per line - Each line must contain exactly one complete JSON value; objects are most common for records
  2. Valid JSON syntax - Each line must be valid JSON according to RFC 8259
  3. Newline separation - Values are separated by newline characters (\n or \r\n)
  4. No array wrapping - The file should not be wrapped in square brackets
  5. No trailing commas - No commas between lines or after the last value
  6. UTF-8 encoding - Files should be encoded in UTF-8 for international character support

Valid NDJSON Examples

valid-example.ndjson
{"id": 1, "name": "John Doe", "active": true}
{"id": 2, "name": "Jane Smith", "active": false}
{"id": 3, "name": "Bob Johnson", "active": true, "tags": ["admin", "user"]}

Invalid NDJSON Examples

The following examples demonstrate common NDJSON format violations:

invalid-array.ndjson
[
{"id": 1, "name": "John"},
{"id": 2, "name": "Jane"}
]

❌ Invalid: Array wrapping not allowed

invalid-commas.ndjson
{"id": 1, "name": "John"},
{"id": 2, "name": "Jane"},

❌ Invalid: Trailing commas not allowed

invalid-syntax.ndjson
{"id": 1, "name": "John"}
{"id": 2, "name": "Jane", "age":}

❌ Invalid: Malformed JSON on second line

Parsing Requirements

A compliant NDJSON parser must handle the following requirements:

  • Line-by-line processing - Parse each line independently
  • Empty line handling - Skip or ignore empty lines
  • Error isolation - Malformed lines should not stop processing of valid lines
  • Encoding support - Support UTF-8 and other common encodings
  • Newline detection - Handle both Unix (\n) and Windows (\r\n) line endings
  • Memory efficiency - Process large files without loading entire content into memory

Implementation Examples

Python Implementation

ndjson_parser.py
import json

def parse_ndjson(file_path):
    """Parse NDJSON file with proper error handling."""
    with open(file_path, 'r', encoding='utf-8') as f:
        for line_num, line in enumerate(f, 1):
            line = line.strip()
            if not line:  # Skip empty lines
                continue
            
            try:
                data = json.loads(line)
                yield data
            except json.JSONDecodeError as e:
                print(f"Error on line {line_num}: {e}")
                continue

# Usage
for record in parse_ndjson('data.ndjson'):
    print(record)

JavaScript Implementation

ndjson_parser.js
const fs = require('fs');
const readline = require('readline');

function parseNDJSON(filePath) {
    return new Promise((resolve, reject) => {
        const results = [];
        const fileStream = fs.createReadStream(filePath);
        const rl = readline.createInterface({
            input: fileStream,
            crlfDelay: Infinity
        });

        rl.on('line', (line) => {
            if (line.trim()) {
                try {
                    const data = JSON.parse(line);
                    results.push(data);
                } catch (error) {
                    console.error(`JSON parse error: ${error.message}`);
                }
            }
        });

        rl.on('close', () => resolve(results));
        rl.on('error', reject);
    });
}

// Usage
parseNDJSON('data.ndjson')
    .then(data => console.log(data))
    .catch(console.error);

Validation Rules

A valid NDJSON file must pass all of the following validation checks:

Check Description Required
JSON Validity Each line must be valid JSON ✅ Yes
Line Separation Values separated by newlines ✅ Yes
No Array Wrapping File not wrapped in square brackets ✅ Yes
No Trailing Commas No commas between or after values ✅ Yes
UTF-8 Encoding File encoded in UTF-8 ✅ Yes
Empty Line Handling Empty lines should be ignored ⚠️ Recommended

MIME Types and File Extensions

NDJSON files should use the following MIME types and file extensions:

MIME Types

  • application/x-ndjson (preferred)
  • application/jsonl
  • text/x-jsonl
  • text/plain (fallback)

File Extensions

  • .ndjson (preferred)
  • .jsonl
  • .jsonlines
  • .txt (fallback)

Performance Considerations

When implementing NDJSON parsers, consider the following performance factors:

  • Streaming - Use streaming parsers for large files to avoid memory issues
  • Line buffering - Read files line by line rather than loading entire content
  • Error handling - Implement efficient error handling that doesn't slow down processing
  • Encoding detection - Detect file encoding efficiently to avoid re-reading
  • Memory management - Process and release objects as soon as possible
  • Parallel processing - Consider parallel processing for CPU-intensive operations

Common Pitfalls and Solutions

Pitfall: Array Wrapping

Many developers mistakenly wrap NDJSON content in square brackets, creating invalid NDJSON.

Solution: Put each complete JSON value on its own line instead of wrapping the file in one outer array.

Pitfall: Trailing Commas

Adding commas between lines or after the last value creates invalid NDJSON.

Solution: Use only newline characters to separate values.

Pitfall: Memory Issues

Loading entire NDJSON files into memory can cause issues with large files.

Solution: Use streaming parsers that process one line at a time.

Testing Your NDJSON Implementation

Use our validation tools to test your NDJSON files and implementations:

Validation Tools

Get Started with NDJSON