NDJSON Specification: Newline Delimited JSON Format Specification
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:
- One JSON value per line - Each line must contain exactly one complete JSON value; objects are most common for records
- Valid JSON syntax - Each line must be valid JSON according to RFC 8259
- Newline separation - Values are separated by newline characters (\n or \r\n)
- No array wrapping - The file should not be wrapped in square brackets
- No trailing commas - No commas between lines or after the last value
- UTF-8 encoding - Files should be encoded in UTF-8 for international character support
Valid NDJSON Examples
{"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:
[
{"id": 1, "name": "John"},
{"id": 2, "name": "Jane"}
]
❌ Invalid: Array wrapping not allowed
{"id": 1, "name": "John"},
{"id": 2, "name": "Jane"},
❌ Invalid: Trailing commas not allowed
{"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
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
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/jsonltext/x-jsonltext/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
- NDJSON Validator - Validate your NDJSON files for syntax errors
- NDJSON Viewer - View and explore NDJSON files online
- JSON to JSONL Converter - Convert JSON arrays to newline-delimited records