JSONL vs JSON — Key Differences and When to Use Each Format
JSON is the universal data format for APIs and configs. JSONL (JSON Lines) is the streaming-friendly alternative for logs, big data, and machine learning. Here's how they compare and when to use each.
What is JSON?
JSON (JavaScript Object Notation) stores structured data as a single root value — typically an object or array. The entire document must be valid and loaded into memory to parse.
{
"users": [
{"id": 1, "name": "Alice", "role": "engineer"},
{"id": 2, "name": "Bob", "role": "designer"},
{"id": 3, "name": "Carol", "role": "manager"}
]
}JSON is the standard for REST APIs, configuration files (package.json, tsconfig.json), and data exchange between services. Almost every language has built-in JSON support.
What is JSONL (JSON Lines)?
JSONL stores each record as a separate, valid JSON object on its own line. No wrapping array, no commas between objects, no trailing commas. Each line is independent.
{"id": 1, "name": "Alice", "role": "engineer"}
{"id": 2, "name": "Bob", "role": "designer"}
{"id": 3, "name": "Carol", "role": "manager"}JSONL is also called NDJSON (Newline-Delimited JSON). The two names refer to the same format. JSONL uses .jsonl extension; NDJSON uses .ndjson.
Key Differences
| Feature | JSON | JSONL |
|---|---|---|
| Structure | Single root value (object/array) | One JSON object per line |
| Parsing | Parse entire file at once | Parse line by line |
| Memory usage | O(n) — entire file in memory | O(1) per record — constant |
| Streaming | Not supported natively | Built-in — read line by line |
| Appending data | Must rewrite entire file | Just append a new line |
| Error recovery | One error breaks entire parse | Skip bad lines, continue |
| Parallel processing | Difficult (nested structure) | Easy (split by lines) |
| File extension | .json | .jsonl or .ndjson |
| Best for | APIs, configs, small datasets | Logs, big data, ML, streaming |
When to Use JSON
When to Use JSONL
Converting Between Formats
JSON Array to JSONL
// Convert a JSON array to JSONL
const data = require('./data.json'); // { "users": [...] }
const jsonl = data.users
.map(user => JSON.stringify(user))
.join('\n');
require('fs').writeFileSync('data.jsonl', jsonl);JSONL to JSON Array
// Convert JSONL back to a JSON array
const fs = require('fs');
const lines = fs.readFileSync('data.jsonl', 'utf8')
.trim()
.split('\n');
const users = lines.map(line => JSON.parse(line));
fs.writeFileSync('data.json', JSON.stringify({ users }, null, 2));Streaming JSONL (Large Files)
// Stream JSONL line by line — constant memory
const readline = require('readline');
const fs = require('fs');
const rl = readline.createInterface({
input: fs.createReadStream('large-data.jsonl'),
});
let count = 0;
rl.on('line', (line) => {
try {
const record = JSON.parse(line);
// Process each record
count++;
} catch {
// Skip malformed lines
console.error('Bad line:', line.slice(0, 100));
}
});
rl.on('close', () => {
console.log(`Processed ${count} records`);
});Frequently Asked Questions
What is the main difference between JSON and JSONL?
JSON stores data as a single root value (object or array) that must be fully loaded into memory to parse. JSONL stores each record as a separate JSON object on its own line, allowing line-by-line streaming with constant memory usage. JSON is best for APIs and configs; JSONL is best for logs, big data, and streaming.
Is JSONL the same as NDJSON?
For practical purposes, yes. Both use newline-delimited JSON objects with the same rules: one JSON object per line, UTF-8 encoding, newline as delimiter. JSONL (jsonlines.org) uses the .jsonl extension; NDJSON (ndjson.org) uses .ndjson. Most tools support both formats interchangeably.
Can I use JSONL for API responses?
JSONL is not standard for REST API responses — use JSON. However, JSONL is the right choice for streaming APIs (Server-Sent Events, WebSocket event streams, Kafka consumers) where you send a continuous stream of records. Some APIs offer both: JSON for single requests, JSONL for bulk/streaming endpoints.
How do I validate JSONL files?
Each line must be a valid JSON object. Validate by parsing each line independently: cat data.jsonl | python3 -c "import sys,json; [json.loads(l) for l in sys.stdin]". Our JSONL Formatter tool validates and formats JSONL files, highlighting any malformed lines.
Key Takeaways
- Use JSON for APIs, configs, and small datasets that fit in memory.
- Use JSONL for logs, big data, streaming, and append-only data.
- JSONL enables line-by-line streaming with O(1) memory per record.
- JSONL and NDJSON are the same format with different names.
- Converting between formats is straightforward —
JSON.stringify()each record and join with newlines.