csv-parser、csvtojson、fast-csv、papaparse はいずれもCSVデータをJavaScriptオブジェクトやJSONに変換するためのnpmパッケージですが、対応環境やAPI設計、パフォーマンス特性に大きな違いがあります。csv-parser と csvtojson、fast-csv はNode.js専用で、ストリーム処理やファイル読み込みに特化しています。一方、papaparse はブラウザとNode.jsの両方で動作し、フロントエンド開発者にとって唯一の選択肢となっています。これらのライブラリは、データの読み込み方法、メモリ使用量、変換機能、エラーハンドリングなど、実際の開発現場で直面する課題に対して異なる解決策を提供しています。
WebアプリケーションでCSVファイルを扱う際、適切なパーサーを選ぶことはパフォーマンスや開発効率に大きく影響します。この記事では、代表的な4つのnpmパッケージ — csv-parser、csvtojson、fast-csv、papaparse — を実践的な観点から比較し、それぞれの強みと使いどころを明らかにします。
csv-parser はNode.js向けに設計されており、主にストリーム経由での処理を想定しています。ファイルパスやReadable Streamを直接扱えますが、ブラウザ環境では使えません。
// csv-parser: Node.js ストリーム処理
const csv = require('csv-parser');
const fs = require('fs');
fs.createReadStream('data.csv')
.pipe(csv())
.on('data', (row) => console.log(row));
csvtojson もNode.js専用ですが、文字列やファイルパス、Bufferなど多様な入力をサポートしています。特に文字列からの変換が簡単です。
// csvtojson: 文字列からの変換
const csv = require('csvtojson');
const csvString = 'name,age\nAlice,30\nBob,25';
const jsonArray = await csv().fromString(csvString);
console.log(jsonArray);
fast-csv はNode.js向けで、ストリームとPromiseの両方に対応しています。ファイル、文字列、配列など柔軟な入力を受け付けます。
// fast-csv: Promiseベースで文字列を処理
const { parse } = require('@fast-csv/parse');
const csvString = 'name,age\nAlice,30\nBob,25';
const rows = await parse(csvString).promise();
console.log(rows);
papaparse は唯一、フロントエンドとバックエンドの両方で動作します。Fileオブジェクト、Blob、文字列、URLなど、ブラウザ特有の入力にも対応しています。
// papaparse: ブラウザでFileオブジェクトを処理
Papa.parse(fileInput.files[0], {
header: true,
complete: (results) => console.log(results.data)
});
すべてのライブラリが「ヘッダー行あり」のCSVをオブジェクト配列に変換できますが、細かい挙動に違いがあります。
csv-parser はデフォルトでヘッダー行をキーとして使用し、各行をオブジェクトに変換します。
// csv-parser: 自動でヘッダーをキーに
fs.createReadStream('users.csv')
.pipe(csv())
.on('data', (row) => {
// row = { name: 'Alice', age: '30' }
});
csvtojson も同様ですが、{ noheader: false }(デフォルト)でヘッダーを使用します。ヘッダーなしCSVも簡単に扱えます。
// csvtojson: ヘッダーなしCSV
const jsonArray = await csv({ noheader: true }).fromString('Alice,30\nBob,25');
// 結果: [{ field1: 'Alice', field2: '30' }, ...]
fast-csv は明示的に{ headers: true }を指定する必要があります。
// fast-csv: ヘッダーを明示
const rows = await parse(csvString, { headers: true }).promise();
// rows = [{ name: 'Alice', age: '30' }, ...]
papaparse はheader: trueオプションでヘッダーを有効にします。
// papaparse: ヘッダー有効化
Papa.parse(csvString, {
header: true,
complete: (results) => console.log(results.data)
});
大規模CSVを処理する場合、メモリ使用量が重要になります。
csv-parser はストリーム専用で、巨大ファイルでも低メモリで処理可能です。ただし、同期的な全データ取得はできません。
csvtojson は内部でバッファリングを行うため、大きなファイルではメモリを大量に消費します。ストリーミングモードもありますが、APIがやや複雑です。
// csvtojson: ストリーミングモード
fs.createReadStream('big.csv')
.pipe(csv())
.on('data', (jsonObj) => console.log(jsonObj))
.on('end', () => console.log('done'));
fast-csv はストリームとPromiseの両方をサポートしており、必要に応じて選べます。ストリームを使えばメモリ効率が良いです。
papaparse はブラウザ向けに最適化されており、worker: trueオプションでWeb Workerを使って重い処理をバックグラウンドで実行できます。これによりUIが固まることを防げます。
// papaparse: Web Workerで非同期処理
Papa.parse(file, {
worker: true,
header: true,
complete: (results) => console.log(results.data)
});
データを単にパースするだけでなく、加工や検証が必要な場合があります。
csv-parser は.map()チェーンで変換できますが、機能は限定的です。
// csv-parser: 値の変換
fs.createReadStream('data.csv')
.pipe(csv())
.pipe(map((row) => ({ ...row, age: Number(row.age) })))
.on('data', console.log);
csvtojson はpreRawDataやpreFileLineなどのフックで柔軟な前処理が可能です。
// csvtojson: 行ごとの前処理
const jsonArray = await csv({
preFileLine: (line, idx) => idx === 0 ? line : line.toUpperCase()
}).fromString(csvString);
fast-csv はtransformオプションで各行を加工できます。
// fast-csv: transformで型変換
const rows = await parse(csvString, {
headers: true,
transform: (row) => ({ ...row, age: Number(row.age) })
}).promise();
papaparse はtransform関数で各セルの値を変更できます。
// papaparse: セル単位の変換
Papa.parse(csvString, {
header: true,
transform: (value, field) => field === 'age' ? Number(value) : value,
complete: (results) => console.log(results.data)
});
これは最も重要な判断基準の一つです。
csv-parser: Node.js専用。ブラウザでは動作しない。csvtojson: Node.js専用。ブラウザ非対応。fast-csv: Node.js専用。ブラウザ非対応。papaparse: ブラウザとNode.jsの両方で動作。フロントエンド開発者にとって唯一の選択肢。| ライブラリ | 環境 | 主な用途 | 特徴 |
|---|---|---|---|
csv-parser | Node.js | ストリーム処理、シンプルな変換 | 軽量、ストリーム専用 |
csvtojson | Node.js | 文字列/ファイル→JSON、柔軟な前処理 | 多機能、メモリ消費大 |
fast-csv | Node.js | 高性能ストリーム、型安全な処理 | モダンAPI、双方向対応 |
papaparse | ブラウザ/Node.js | フロントエンドCSV処理、Worker対応 | ユニバーサル、高機能 |
papaparse を選んでください。他の3つはブラウザで動作しません。csv-parser(シンプルさ重視)か fast-csv(モダンAPI・型安全性重視)が適しています。csvtojson の豊富なオプションが便利です。正しいツールを選ぶことで、コードの可読性、パフォーマンス、保守性が大きく変わります。プロジェクトの要件に合わせて最適なライブラリを選びましょう。
papaparseはフロントエンドでCSVを処理する必要がある場合に唯一の選択肢です。Fileオブジェクト、Blob、文字列などブラウザ特有の入力に対応しており、Web Workerによるバックグラウンド処理も可能でUIのフリーズを防げます。Node.jsでも動作するため、ユニバーサルなアプリケーション開発にも適しています。ただし、Node.js専用の高度なストリーム機能は他ライブラリほど充実していません。
fast-csvはNode.js環境で高性能かつ型安全なCSV処理を求める場合に最適です。ストリームとPromiseの両方をサポートしており、transformオプションによる各行の加工も容易です。TypeScriptとの相性も良く、大規模プロジェクトでの堅牢性を重視する場合に推奨されます。ただし、ブラウザ環境では使用できない点に注意してください。
csv-parserはNode.js環境でシンプルかつ軽量なストリーム処理が必要な場合に最適です。巨大なCSVファイルを低メモリで逐次処理したいときや、他の変換ロジックを自前で実装したい場合に向いています。ただし、ブラウザ環境では使用できず、高度な変換機能は備えていないため、複雑な前処理が必要なケースには不向きです。
csvtojsonはNode.js上でCSVをJSONに変換する必要があり、かつ柔軟な前処理やカスタマイズが必要な場合に適しています。文字列やファイルからの変換が簡単で、preFileLineやpreRawDataといったフックによる細かい制御が可能です。ただし、大規模データではメモリを大量に消費するため、ストリーム処理が必須のシナリオでは注意が必要です。
Papa Parse is the fastest in-browser CSV (or delimited text) parser for JavaScript. It is reliable and correct according to RFC 4180, and it comes with these features:
<input type="file"> elementsPapa Parse has no dependencies - not even jQuery.
papaparse is available on npm. It can be installed with the following command:
npm install papaparse
If you don't want to use npm, papaparse.min.js can be downloaded to your project source.
import Papa from 'papaparse';
Papa.parse(file, config);
const csv = Papa.unparse(data[, config]);
To learn how to use Papa Parse:
The website is hosted on Github Pages. Its content is also included in the docs folder of this repository. If you want to contribute on it just clone the master of this repository and open a pull request.
Papa Parse can parse a Readable Stream instead of a File when used in Node.js environments (in addition to plain strings). In this mode, encoding must, if specified, be a Node-supported character encoding. The Papa.LocalChunkSize, Papa.RemoteChunkSize , download, withCredentials and worker config options are unavailable.
Papa Parse can also parse in a node streaming style which makes .pipe available. Simply pipe the Readable Stream to the stream returned from Papa.parse(Papa.NODE_STREAM_INPUT, options). The Papa.LocalChunkSize, Papa.RemoteChunkSize , download, withCredentials, worker, step, and complete config options are unavailable. To register a callback with the stream to process data, use the data event like so: stream.on('data', callback) and to signal the end of stream, use the 'end' event like so: stream.on('end', callback).
For usage instructions, see the homepage and, for more detail, the documentation.
Papa Parse is under test. Download this repository, run npm install, then npm test to run the tests.
To discuss a new feature or ask a question, open an issue. To fix a bug, submit a pull request to be credited with the contributors! Remember, a pull request, with test, is best. You may also discuss on Twitter with #PapaParse or directly to me, @mholt6.
If you contribute a patch, ensure the tests suite is running correctly. We run continuous integration on each pull request and will not accept a patch that breaks the tests.