NDJSON完全ガイド:改行区切りJSON徹底解説
Newline Delimited JSON(NDJSON)に関する包括的ガイド。仕様、MIMEタイプ、Python、Node.js、コマンドラインでのNDJSONの読み書き、ストリーミングHTTP APIでの使用、そしてJSONLとの関係を学びます。
最終更新:2026年2月
NDJSONとは?
NDJSONはNewline Delimited JSONの略です。各行に正確に1つの有効なJSON値が含まれ、改行文字(\n)で区切られたテキストベースのデータフォーマットです。このフォーマットは、ファイル全体をメモリに読み込むことなく、大規模なデータセットをストリーミングして処理するために設計されました。すべてを単一の配列やオブジェクトでラップする標準的なJSONファイルとは異なり、NDJSONではレコードを1つずつ読み取り、書き込み、処理できます。
NDJSONの仕様はgithub.com/ndjson/ndjson-specでホストされています。ログ配信、データパイプライン、HTTPストリーミングAPIですでに一般的になっていたパターンを正式化するために作成されました。各行は自己完結型です:1行に無効なJSONが含まれていても、他の行は正常にパースできます。これにより、NDJSONはアプリケーションログ、イベントストリーム、増分データエクスポートなどの追記専用ワークフローに耐障害性があり、適しています。
{"id":1,"event":"page_view","url":"/home"}{"id":2,"event":"click","url":"/pricing"}{"id":3,"event":"signup","url":"/register"}
NDJSONの仕様
github.com/ndjson/ndjson-specの公式NDJSON仕様は意図的にミニマルです。単一のテキストストリームで複数のJSON値をシリアライズするためのシンプルな慣例を定義しています。コアルールは簡潔です:
仕様はフォーマットにヘッダー、メタデータ、スキーマ情報を追加することを明示的に避けています。これにより、NDJSONは可能な限りシンプルに保たれ、標準的なUnixテキスト処理ツールと互換性があります。各行には任意の有効なJSON値が許可されますが、実際にはほとんどのNDJSONファイルは一貫したキーセットを持つJSONオブジェクトを含んでいます。
- 各行には正確に1つの有効なJSON値(オブジェクト、配列、文字列、数値、ブール値、またはnull)を含める必要があります。
- 行は改行文字 '\n'(U+000A)で区切られます。キャリッジリターン '\r'(U+000D)は '\n' の前に表示される場合がありますが、必須ではありません。
- 最後のJSON値の後の末尾の改行は許可されますが、必須ではありません。
- 各JSON値には、値自体の中にエスケープされていない改行文字を含めてはなりません。
ルールがミニマルであるため、NDJSONはJSONシリアライザーを持つ任意のプログラミング言語から簡単に生成できます。各レコードをシリアライズし、改行を追加して出力に書き込むだけです。閉じ括弧も、末尾のカンマも、囲む配列構造も気にする必要がありません。
NDJSON vs JSON vs JSONL
NDJSON、JSON、JSONLはそれぞれ異なる構造を持っています。標準JSONは単一の値(通常は配列またはオブジェクト)をエンコードします。JSONLとNDJSONはどちらも1行に1つのJSON値を格納し、機能的に同一です。以下の表は、3つのフォーマット間の主な違いを示しています。
| 特徴 | JSON | JSONL | NDJSON |
|---|---|---|---|
| 正式名称 | JavaScript Object Notation | JSON Lines | Newline Delimited JSON |
| ファイル拡張子 | .json | .jsonl | .ndjson |
| MIMEタイプ | application/json | application/jsonl(非公式) | application/x-ndjson |
| 仕様 | RFC 8259(IETF標準) | jsonlines.org(コミュニティ) | github.com/ndjson/ndjson-spec(コミュニティ) |
| 行区切り文字 | N/A(単一値) | \n(改行) | \n(改行) |
| 末尾の改行 | N/A | 推奨 | 任意 |
| ストリーミング対応 | いいえ(ドキュメント全体のパースが必要) | はい(行単位) | はい(行単位) |
NDJSON MIMEタイプ:application/x-ndjson
NDJSONの登録済みMIMEタイプはapplication/x-ndjsonです。このコンテンツタイプは、レスポンスボディが改行区切りのJSONデータを含むことを示すためにHTTPヘッダーで使用されます。GitHub API、Docker Registry API、Elasticsearch Bulk APIを含む多くのストリーミングAPIが、NDJSONレスポンスを配信するためにこのMIMEタイプを使用しています。
Content-Type: application/x-ndjson# Example: curl a streaming APIcurl -H "Accept: application/x-ndjson" https://api.example.com/events/stream# Example: Express.js responseres.setHeader('Content-Type', 'application/x-ndjson');res.write(JSON.stringify(record) + '\n');
一部のAPIは代替としてapplication/json-seq(RFC 7464)やtext/plainも受け付けます。ただし、application/x-ndjsonは改行区切りJSONストリームで最も広く採用されているMIMEタイプです。JSONレコードをストリーミングする新しいAPIを構築する場合は、最大限の互換性のためにapplication/x-ndjsonを使用してください。
NDJSONの読み書き
NDJSONの操作は、JSONをサポートする任意の言語で簡単です。以下にPython、Node.js、コマンドラインの実用的な例を示します。
Pythonの組み込みjsonモジュールはNDJSONを自然に処理します。ファイルから行を読み取り、各行をjson.loadsでパースし、json.dumpsで書き込みます。大きなファイルの場合、この行単位のアプローチは一定のメモリを使用します。
guide-ndjson-complete-guide.ndjsonGuide.readWrite.python.code
Node.jsでは、readlineモジュールとfs.createReadStreamを使用してNDJSONファイルを効率的にパースします。ストリームは一度に1行ずつ処理するため、ファイルサイズに関係なくメモリ使用量を低く保ちます。
import { createReadStream, writeFileSync } from 'node:fs';import { createInterface } from 'node:readline';// Read NDJSONasync 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 NDJSONconst 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');
jqコマンドラインツールはNDJSON入力をネイティブに理解します。--slurpフラグを使用してすべてのレコードを配列に収集するか、フラグなしで各レコードを個別に処理します。
# 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 fieldsjq {id, url} data.ndjson# Count total recordsjq -s 'length' data.ndjson# Convert NDJSON to a JSON arrayjq -s '.' data.ndjson > data.json# Convert a JSON array back to NDJSONjq -c '.[]' data.json > data.ndjson
HTTPストリーミングAPIでのNDJSON
NDJSONはリアルタイムデータを配信するHTTPストリーミングAPIの事実上の標準です。サーバーがNDJSONレスポンスを送信すると、クライアントはレスポンス全体の完了を待つことなく、最初のレコードが到着した時点で処理を開始できます。これは大きなJSON配列を返すよりも高速でメモリ効率が良いです。
NDJSONストリーミングを使用する人気のあるサービスには、Docker Registry(イメージレイヤーイベント)、Elasticsearch(バルク操作)、Apache CouchDB(変更フィード)、および多くの最新のイベント駆動型APIがあります。このパターンは、Server-Sent Eventsの代替、リアルタイムログテーリング、Webアプリケーションでのプログレッシブデータロードに適しています。
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 eventslet 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);
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);}// Usagefor await (const event of readNdjsonStream('/api/events/stream')) {console.log('Received:', event);}
NDJSONエコシステムツール
NDJSONをネイティブにサポートするコマンドラインツールとライブラリのエコシステムが拡大しています。これらのツールにより、カスタムコードを書くことなくNDJSONデータのフィルタリング、変換、分析が可能です。
jq
必須jqは最も人気のあるコマンドラインJSONプロセッサーです。デフォルトでNDJSON(1行に1つのJSON値)を読み取り、フィルタリング、マッピング、グループ化、再フォーマットをサポートします。コンパクトな出力にはjq -cを、すべてのレコードを配列に集約するにはjq -sを使用します。
ndjson-cli
CLIndjson-cliは、NDJSONストリームを操作するためのUnixスタイルコマンドのコレクションです:ndjson-filter、ndjson-map、ndjson-reduce、ndjson-sort、ndjson-join。各コマンドはstdinから読み取り、stdoutに書き込むため、パイプで合成可能です。
ndjson(npm)
Node.jsndjson npmパッケージは、Node.js用のストリーミングNDJSONパーサーとシリアライザーを提供します。ndjson.parse()とndjson.stringify()のtransform streamsを公開し、高スループットデータ処理のためにNode.jsストリームパイプラインに直接統合できます。
NDJSONとJSONL:相互運用性
NDJSONとJSONL(JSON Lines)は機能的に同一のフォーマットです。どちらも改行で区切られた1行に1つのJSON値を格納します。有効なNDJSONファイルは有効なJSONLでもあり、その逆もまた然りです。.ndjsonファイルを.jsonlに(またはその逆に)ファイル名を変更しても、コンテンツの1バイトも変更することなく、一方のフォーマットを読み取るすべてのツールが他方も読み取ります。
唯一の違いは外見的なものです:NDJSONはgithub.com/ndjson/ndjson-specに由来し、.ndjson拡張子とapplication/x-ndjson MIMEタイプを使用し、JSONLはjsonlines.orgに由来し、.jsonl拡張子を使用します。実際には、ほとんどの開発者は2つの名前を同義語として扱います。プロジェクトですでにJSONLを使用している場合、NDJSONに移行する必要はなく、ライブラリがNDJSONをサポートしていると言っている場合、変更なしで.jsonlファイルでも動作します。
無料のNDJSON/JSONLツールを試す
ブラウザでNDJSONとJSONLファイルを操作できます。すべての処理はローカルで行われるため、データはプライベートに保たれます。