JavaScript で JSONL を扱う:読み取り・書き込み・解析
JavaScript で JSONL(JSON Lines)ファイルを扱うための完全ガイド。組み込み API と人気ライブラリを使用して、Node.js とブラウザの両方で JSONL データの読み取り、書き込み、解析、ストリーミングを学びます。
最終更新:2026年2月
なぜ JavaScript で JSONL を扱うのか?
JavaScript は JSONL ファイルを扱うのに最適な言語です。JSON はもともと JavaScript から生まれたものであり、組み込みの JSON.parse() と JSON.stringify() メソッドによるファーストクラスの解析サポートを備えています。Node.js のデータパイプラインの構築、サーバー上でのログファイル処理、ブラウザでのユーザーによる JSONL アップロードなど、JavaScript はあらゆるステップに対応するツールを提供します。
JSONL(JSON Lines)は 1 行に 1 つの JSON オブジェクトを格納するため、ストリーミング、追記専用ログ、大規模データセットの行単位処理に最適です。Node.js のストリームはこの形式と完全に適合し、メモリ不足になることなく数百万件のレコードを読み取り・変換できます。クライアント側では、ブラウザの FileReader API と Streams API により、ユーザーのデバイス上で完全に JSONL 処理が可能です。このガイドでは、Node.js とブラウザの両方で JSONL を読み取る方法、JSONL ファイルの書き込み、ストリーミング変換パイプラインの構築、プロジェクトに適した npm ライブラリの選択方法を学びます。
Node.js で JSONL を読み取る
Node.js は readline モジュールを使用してファイルを効率的に行単位で読み取ることができます。fs.createReadStream と組み合わせることで、ファイル全体をメモリに読み込む代わりにデータをストリーミングするため、サーバー上で JSONL ファイルを処理する推奨方法です。
fs.createReadStream を readline.createInterface にパイプして、JSONL ファイルを 1 行ずつ読み取ります。このアプローチはファイルサイズに関係なく最小限のメモリで動作します。
import { createReadStream } from 'node:fs';import { createInterface } from 'node:readline';async function readJsonl(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;}// Usageconst data = await readJsonl('data.jsonl');console.log(`Loaded ${data.length} records`);console.log(data[0]);
メモリに余裕がある小さな JSONL ファイルの場合、ファイル全体を一度に読み込んで改行で分割できます。ストリーミング効率の代わりにシンプルさを重視したアプローチです。
import { readFileSync } from 'node:fs';const records = readFileSync('data.jsonl', 'utf-8').split('\n').filter(line => line.trim()).map(line => JSON.parse(line));console.log(`Loaded ${records.length} records`);
ブラウザで JSONL を読み取る
ブラウザでは、ユーザーがファイル入力を通じて JSONL ファイルをアップロードできます。FileReader API または最新の Streams API を使用してファイルを読み取ることができ、サーバーにデータを送信する必要はありません。
FileReader を使用してユーザーが選択したファイルを読み取り、テキストコンテンツを行に分割して各行を解析します。すべてのデータをクライアント側で保持するためプライバシーが守られます。
function parseJsonlFile(file) {return new Promise((resolve, reject) => {const reader = new FileReader();reader.onload = () => {const text = reader.result;const records = text.split('\n').filter(line => line.trim()).map(line => JSON.parse(line));resolve(records);};reader.onerror = () => reject(reader.error);reader.readAsText(file, 'utf-8');});}// Usage with an <input type="file"> elementconst input = document.querySelector('input[type="file"]');input.addEventListener('change', async (e) => {const file = e.target.files[0];const records = await parseJsonlFile(file);console.log(`Parsed ${records.length} records`);});
ブラウザで大容量ファイルを処理する場合、Streams API と TextDecoderStream を使用してファイルをチャンク単位で処理します。ファイル全体を一度にメモリに読み込むことを回避できます。
async function* streamJsonl(file) {const stream = file.stream().pipeThrough(new TextDecoderStream());const reader = stream.getReader();let buffer = '';while (true) {const { done, value } = await reader.read();if (done) break;buffer += value;const lines = buffer.split('\n');buffer = lines.pop(); // Keep incomplete last linefor (const line of lines) {const trimmed = line.trim();if (trimmed) yield JSON.parse(trimmed);}}// Handle remaining bufferif (buffer.trim()) {yield JSON.parse(buffer.trim());}}// Usagefor await (const record of streamJsonl(file)) {console.log(record);}
Node.js で JSONL を書き込む
Node.js で JSONL ファイルを書き込むのは簡単です。各 JavaScript オブジェクトを JSON 文字列にシリアライズし、改行文字を追加します。大規模データセットでは、メモリ内で文字列全体を構築する代わりに、書き込みストリームを使用することでパフォーマンスが向上します。
fs.writeFileSync または fs.createWriteStream を使用してレコードを JSONL ファイルに書き込みます。各レコードは有効な JSON の 1 行に続く改行文字です。
import { writeFileSync } from 'node:fs';const records = [{ id: 1, name: 'Alice', role: 'engineer' },{ id: 2, name: 'Bob', role: 'designer' },{ id: 3, name: 'Charlie', role: 'manager' },];const jsonl = records.map(record => JSON.stringify(record)).join('\n') + '\n';writeFileSync('output.jsonl', jsonl, 'utf-8');console.log(`Wrote ${records.length} records`);
数百万件のレコードを書き込む場合、出力文字列全体をメモリ内で構築しないように書き込みストリームを使用します。ストリームはバックプレッシャーを自動的に処理し、OS バッファがいっぱいになると書き込みを一時停止します。
import { createWriteStream } from 'node:fs';async function writeJsonl(filePath, records) {const stream = createWriteStream(filePath, 'utf-8');for (const record of records) {const line = JSON.stringify(record) + '\n';// Respect backpressureif (!stream.write(line)) {await new Promise(resolve => stream.once('drain', resolve));}}stream.end();await new Promise(resolve => stream.on('finish', resolve));console.log('Write complete');}// Usageconst data = Array.from({ length: 100000 }, (_, i) => ({id: i + 1,value: Math.random(),timestamp: new Date().toISOString(),}));await writeJsonl('large_output.jsonl', data);
JSONL パイプライン向けの Transform ストリーム
Node.js の Transform ストリームを使用すると、JSONL を読み取り、各レコードを処理し、結果を書き込む構成可能なデータパイプラインを構築できます。このパターンは ETL ジョブ、ログ処理、データ移行に最適です。
import { createReadStream, createWriteStream } from 'node:fs';import { createInterface } from 'node:readline';import { Transform } from 'node:stream';import { pipeline } from 'node:stream/promises';// Transform: parse JSONL line into object, process, stringify backconst transformJsonl = new Transform({objectMode: true,transform(chunk, encoding, callback) {const line = chunk.toString().trim();if (!line) return callback();try {const record = JSON.parse(line);// Add your transformation hererecord.processed = true;record.processedAt = new Date().toISOString();callback(null, JSON.stringify(record) + '\n');} catch (err) {callback(err);}},});// Build the pipelineconst rl = createInterface({input: createReadStream('input.jsonl', 'utf-8'),crlfDelay: Infinity,});const output = createWriteStream('output.jsonl', 'utf-8');for await (const line of rl) {transformJsonl.write(line);}transformJsonl.end();await pipeline(transformJsonl, output);console.log('Pipeline complete');
このパイプラインは JSONL ファイルを行単位で読み取り、各レコードに変換を適用し(processed と processedAt フィールドを追加)、結果を新しいファイルに書き込みます。Transform ストリームはバックプレッシャーを自動的に処理するため、非常に大きなファイルでもメモリ使用量は一定に保たれます。複雑な ETL ワークフローでは複数の変換をチェーンできます。
JSONL 向け JavaScript ライブラリ
組み込みの JSON.parse がほとんどのケースをうまく処理しますが、ストリーミング、バリデーション、バッチ処理など JSONL 固有のワークフローに便利なユーティリティを提供する npm パッケージがいくつかあります。
JSON.parse(組み込み)
組み込み組み込みの JSON.parse() と JSON.stringify() は V8 で高度に最適化されており、ほとんどの JSONL ユースケースに十分です。readline と組み合わせてストリーミングに使用します。依存関係不要で、数百 MB までのファイルに対して優れたパフォーマンスを発揮します。
ndjson
人気ndjson は、Node.js ストリームと互換性のあるストリーミング JSONL(改行区切り JSON)パーサーとシリアライザーを提供する人気の npm パッケージです。解析エラーを適切に処理し、既存のストリームパイプラインとうまく統合できます。迅速なプロトタイピングに最適です。
jsonl-parse-stringify
シンプルjsonl-parse-stringify は、JSONL データ用のシンプルな parse() と stringify() メソッドを提供する軽量でゼロ依存のライブラリです。末尾の改行や空行などのエッジケースを処理します。ストリームのセットアップなしでクリーンな同期 API が必要な場合に最適です。
無料の JSONL ツールを試す
コードを書きたくないですか?無料のオンラインツールを使って、ブラウザで直接 JSONL ファイルの表示、変換、フォーマットができます。すべての処理はローカルで行われるため、データのプライバシーが守られます。