Guida Completa NDJSON: Newline Delimited JSON Spiegato

Una guida completa al Newline Delimited JSON (NDJSON). Scopri le specifiche, il tipo MIME, come leggere e scrivere NDJSON in Python, Node.js e da riga di comando, usarlo nelle API HTTP in streaming e comprendere la sua relazione con JSONL.

Ultimo aggiornamento: Febbraio 2026

Cos'è NDJSON?

NDJSON sta per Newline Delimited JSON. È un formato di dati testuale in cui ogni riga contiene esattamente un valore JSON valido, separato da un carattere di nuova riga (\n). Il formato è stato progettato per lo streaming e l'elaborazione di grandi dataset senza caricare l'intero file in memoria. A differenza di un file JSON standard che racchiude tutto in un singolo array o oggetto, NDJSON permette di leggere, scrivere ed elaborare record uno alla volta.

La specifica NDJSON è ospitata su github.com/ndjson/ndjson-spec. È stata creata per formalizzare un pattern già comune nello shipping dei log, nelle pipeline di dati e nelle API HTTP in streaming. Ogni riga è autonoma: se una riga contiene JSON non valido, le altre righe possono comunque essere analizzate con successo. Questo rende NDJSON tollerante agli errori e adatto per flussi di lavoro append-only come log delle applicazioni, stream di eventi ed esportazioni incrementali di dati.

Esempio NDJSON (3 record)
{"id":1,"event":"page_view","url":"/home"}
{"id":2,"event":"click","url":"/pricing"}
{"id":3,"event":"signup","url":"/register"}

La Specifica NDJSON

La specifica ufficiale NDJSON su github.com/ndjson/ndjson-spec è intenzionalmente minimale. Definisce una semplice convenzione per serializzare più valori JSON in un singolo flusso di testo. Le regole fondamentali sono dirette:

La specifica evita esplicitamente di aggiungere intestazioni, metadati o informazioni sullo schema al formato. Questo mantiene NDJSON il più semplice possibile e compatibile con gli strumenti standard di elaborazione testo Unix. Qualsiasi valore JSON valido è consentito su ogni riga, anche se nella pratica la maggior parte dei file NDJSON contiene oggetti JSON con un insieme coerente di chiavi.

  • Ogni riga DEVE contenere esattamente un valore JSON valido (oggetto, array, stringa, numero, booleano o null).
  • Le righe sono separate dal carattere di nuova riga '\n' (U+000A). Il ritorno a capo '\r' (U+000D) può apparire prima di '\n' ma non è richiesto.
  • È consentita una nuova riga finale dopo l'ultimo valore JSON ma non è richiesta.
  • Ogni valore JSON non deve contenere caratteri di nuova riga non escapati all'interno del valore stesso.

Poiché le regole sono minimali, NDJSON è facile da generare da qualsiasi linguaggio di programmazione che abbia un serializzatore JSON. Basta serializzare ogni record, aggiungere una nuova riga e scriverlo nell'output. Nessuna parentesi di chiusura, nessuna virgola finale, nessuna struttura di array che li racchiuda.

NDJSON vs JSON vs JSONL

NDJSON, JSON e JSONL hanno ciascuno una struttura diversa. Il JSON standard codifica un singolo valore (di solito un array o un oggetto). JSONL e NDJSON memorizzano entrambi un valore JSON per riga, e sono funzionalmente identici tra loro. La tabella seguente evidenzia le differenze principali tra tutti e tre i formati.

CaratteristicaJSONJSONLNDJSON
Nome CompletoJavaScript Object NotationJSON LinesNewline Delimited JSON
Estensione File.json.jsonl.ndjson
Tipo MIMEapplication/jsonapplication/jsonl (non ufficiale)application/x-ndjson
SpecificaRFC 8259 (standard IETF)jsonlines.org (community)github.com/ndjson/ndjson-spec (community)
Delimitatore di RigaN/A (valore singolo)\n (nuova riga)\n (nuova riga)
Nuova Riga FinaleN/ARaccomandataOpzionale
Adatto allo StreamingNo (deve analizzare l'intero documento)Sì (riga per riga)Sì (riga per riga)

Tipo MIME NDJSON: application/x-ndjson

Il tipo MIME registrato per NDJSON è application/x-ndjson. Questo content type viene usato negli header HTTP per indicare che il corpo della risposta contiene dati JSON delimitati da nuova riga. Molte API in streaming, tra cui l'API di GitHub, l'API del Docker Registry e l'API bulk di Elasticsearch, usano questo tipo MIME per fornire risposte NDJSON.

Header HTTP Content-Type
Content-Type: application/x-ndjson
# Example: curl a streaming API
curl -H "Accept: application/x-ndjson" https://api.example.com/events/stream
# Example: Express.js response
res.setHeader('Content-Type', 'application/x-ndjson');
res.write(JSON.stringify(record) + '\n');

Alcune API accettano anche application/json-seq (RFC 7464) o text/plain come alternative. Tuttavia, application/x-ndjson è il tipo MIME più ampiamente adottato per gli stream JSON delimitati da nuova riga. Quando costruisci una nuova API che trasmette record JSON in streaming, usa application/x-ndjson per la massima compatibilità.

Leggere e Scrivere NDJSON

Lavorare con NDJSON è semplice in qualsiasi linguaggio che supporti JSON. Di seguito esempi pratici per Python, Node.js e la riga di comando.

Il modulo json integrato di Python gestisce NDJSON in modo naturale. Leggi le righe da un file, analizza ciascuna con json.loads e scrivi con json.dumps. Per file di grandi dimensioni, questo approccio riga per riga usa memoria costante.

Python: Leggere e Scrivere NDJSON
guide-ndjson-complete-guide.ndjsonGuide.readWrite.python.code

In Node.js, usa il modulo readline con fs.createReadStream per analizzare file NDJSON in modo efficiente. Lo stream elabora una riga alla volta, mantenendo basso l'uso della memoria indipendentemente dalla dimensione del file.

Node.js: Leggere e Scrivere NDJSON
import { createReadStream, writeFileSync } from 'node:fs';
import { createInterface } from 'node:readline';
// Read NDJSON
async function readNdjson(filePath) {
const records = [];
const rl = createInterface({
input: createReadStream(filePath, 'utf-8'),
crlfDelay: Infinity,
});
for await (const line of rl) {
const trimmed = line.trim();
if (trimmed) records.push(JSON.parse(trimmed));
}
return records;
}
// Write NDJSON
const data = [
{ id: 1, event: 'page_view' },
{ id: 2, event: 'click' },
];
const ndjson = data.map(r => JSON.stringify(r)).join('\n') + '\n';
writeFileSync('output.ndjson', ndjson, 'utf-8');

Lo strumento da riga di comando jq comprende nativamente l'input NDJSON. Usa il flag --slurp per raccogliere tutti i record in un array, oppure elabora ogni record individualmente senza flag.

Riga di Comando: Elaborare NDJSON con jq
# Print each record (jq reads NDJSON by default)
jq '.' data.ndjson
# Filter records where event is "click"
jq 'select(.event == "click")' data.ndjson
# Extract specific fields
jq {id, url} data.ndjson
# Count total records
jq -s 'length' data.ndjson
# Convert NDJSON to a JSON array
jq -s '.' data.ndjson > data.json
# Convert a JSON array back to NDJSON
jq -c '.[]' data.json > data.ndjson

NDJSON nelle API HTTP in Streaming

NDJSON è lo standard de facto per le API HTTP in streaming che forniscono dati in tempo reale. Quando un server invia una risposta NDJSON, il client può iniziare a elaborare il primo record non appena arriva, senza aspettare che l'intera risposta sia completa. Questo è più veloce e più efficiente in termini di memoria rispetto a restituire un grande array JSON.

Servizi popolari che usano lo streaming NDJSON includono Docker Registry (eventi dei layer di immagini), Elasticsearch (operazioni bulk), Apache CouchDB (feed delle modifiche) e molte API moderne event-driven. Il pattern funziona bene con alternative ai Server-Sent Events, tailing di log in tempo reale e caricamento progressivo dei dati nelle applicazioni web.

Server di Streaming NDJSON con Express.js
import express from 'express';
const app = express();
app.get('/api/events/stream', (req, res) => {
res.setHeader('Content-Type', 'application/x-ndjson');
res.setHeader('Transfer-Encoding', 'chunked');
// Simulate streaming events
let id = 0;
const interval = setInterval(() => {
id++;
const event = {
id,
type: 'heartbeat',
timestamp: new Date().toISOString(),
};
res.write(JSON.stringify(event) + '\n');
if (id >= 100) {
clearInterval(interval);
res.end();
}
}, 100);
req.on('close', () => clearInterval(interval));
});
app.listen(3000);
Browser: Consumare Stream NDJSON con Fetch
async function* readNdjsonStream(url) {
const response = await fetch(url, {
headers: { 'Accept': 'application/x-ndjson' },
});
const reader = response.body
.pipeThrough(new TextDecoderStream())
.getReader();
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += value;
const lines = buffer.split('\n');
buffer = lines.pop();
for (const line of lines) {
if (line.trim()) yield JSON.parse(line);
}
}
if (buffer.trim()) yield JSON.parse(buffer);
}
// Usage
for await (const event of readNdjsonStream('/api/events/stream')) {
console.log('Received:', event);
}

Strumenti dell'Ecosistema NDJSON

Un ecosistema in crescita di strumenti da riga di comando e librerie supporta NDJSON nativamente. Questi strumenti permettono di filtrare, trasformare e analizzare dati NDJSON senza scrivere codice personalizzato.

jq

Essenziale

jq è il processore JSON da riga di comando più popolare. Legge NDJSON per default (un valore JSON per riga) e supporta filtraggio, mapping, raggruppamento e riformattazione. Usa jq -c per output compatto e jq -s per raccogliere tutti i record in un array.

ndjson-cli

CLI

ndjson-cli è una collezione di comandi in stile Unix per manipolare stream NDJSON: ndjson-filter, ndjson-map, ndjson-reduce, ndjson-sort e ndjson-join. Ogni comando legge da stdin e scrive su stdout, rendendoli componibili con le pipe.

ndjson (npm)

Node.js

Il pacchetto npm ndjson fornisce parser e serializzatori NDJSON in streaming per Node.js. Espone transform stream ndjson.parse() e ndjson.stringify() che si integrano direttamente nelle pipeline stream di Node.js per l'elaborazione dati ad alto throughput.

NDJSON e JSONL: Interoperabilità

NDJSON e JSONL (JSON Lines) sono formati funzionalmente identici. Entrambi memorizzano un valore JSON per riga, separato da caratteri di nuova riga. Un file NDJSON valido è anche un file JSONL valido, e viceversa. Puoi rinominare un file .ndjson in .jsonl (o viceversa) senza cambiare un singolo byte di contenuto, e ogni strumento che legge un formato leggerà anche l'altro.

Le uniche differenze sono cosmetiche: NDJSON proviene da github.com/ndjson/ndjson-spec e usa l'estensione .ndjson con il tipo MIME application/x-ndjson, mentre JSONL proviene da jsonlines.org e usa l'estensione .jsonl. Nella pratica, la maggior parte degli sviluppatori tratta i due nomi come sinonimi. Se il tuo progetto usa già JSONL, non c'è bisogno di migrare a NDJSON, e se una libreria dice di supportare NDJSON, funzionerà con i tuoi file .jsonl senza alcuna modifica.

JSONL vs NDJSON: Confronto Dettagliato

Per un approfondimento sulla storia, le differenze nelle specifiche e l'adozione nella community di JSONL e NDJSON, leggi la nostra guida di confronto dedicata.

Prova i Nostri Strumenti NDJSON/JSONL Gratuiti

Lavora con file NDJSON e JSONL direttamente nel tuo browser. Tutta l'elaborazione avviene localmente, quindi i tuoi dati restano privati.

Lavora con File NDJSON Online

Visualizza, valida e converti file NDJSON e JSONL fino a 1 GB direttamente nel tuo browser. Nessun upload richiesto, 100% privato.

Domande Frequenti

Guida al Formato NDJSON — Newline Delimited JSON e JSONL ...