csv-parse vs csv-parser vs fast-csv vs papaparse
フロントエンドでのCSVパースライブラリ選定ガイド
csv-parsecsv-parserfast-csvpapaparse類似パッケージ:

フロントエンドでのCSVパースライブラリ選定ガイド

csv-parsecsv-parserfast-csvpapaparse はいずれも CSV(Comma-Separated Values)データを JavaScript オブジェクトや配列に変換するためのライブラリですが、設計思想や使用可能な環境、API のスタイルが大きく異なります。これらのライブラリは、Node.js 環境向け、ブラウザ向け、あるいはその両方で動作するものがあり、ストリーム処理に対応しているか、同期・非同期どちらのインターフェースを提供しているかなど、実際の開発要件によって最適な選択肢が変わります。特に、フロントエンド開発者はファイルアップロード後のブラウザ内パースや、大規模データの効率的な処理といったユースケースを考慮する必要があります。

npmのダウンロードトレンド

3 年

GitHub Starsランキング

統計詳細

パッケージ
ダウンロード数
Stars
サイズ
Issues
公開日時
ライセンス
csv-parse10,617,8744,2561.44 MB497ヶ月前MIT
csv-parser2,229,1751,49329.5 kB601年前MIT
fast-csv01,7747.03 kB587ヶ月前MIT
papaparse013,385264 kB2139ヶ月前MIT

CSV パースライブラリ徹底比較:csv-parse、csv-parser、fast-csv、papaparse

フロントエンド開発で CSV ファイルを扱う際、「どのライブラリを使えばいいか?」という疑問に直面することがよくあります。一見どれも同じように見えますが、実際には設計思想、対応環境、API スタイル、保守状況が大きく異なります。この記事では、4つの主要な CSV パースライブラリを、実際のコードを交えながら深く比較します。

⚠️ まず確認:非推奨パッケージの有無

最初に重要なポイントとして、csv-parser は現在非推奨(deprecated)の可能性があります。npm 公式ページ(2024年時点)には「This package may no longer be maintained or supported.」という明確な警告が記載されています。新規プロジェクトでは使用を避け、代わりに papaparsecsv-parse を検討すべきです。

🌐 実行環境:ブラウザ vs Node.js

papaparse — ブラウザファースト設計

papaparseブラウザでの使用を第一に設計されています。File オブジェクト、Blob、文字列のいずれからも直接パースでき、Web Worker を使って UI をブロックせずに処理できます。

// ブラウザ: File オブジェクトから直接パース
const fileInput = document.getElementById('csv-file');
fileInput.addEventListener('change', (e) => {
  const file = e.target.files[0];
  Papa.parse(file, {
    header: true,
    complete: (results) => console.log(results.data)
  });
});

Node.js でも使えますが、主な強みはフロントエンドにあります。

csv-parse — Node.js 向けの高機能パーサー

csv-parseNode.js 向けに最適化されており、ストリーム処理に完全対応しています。ブラウザでも動作しますが、バンドルサイズが大きくなる可能性があります。

// Node.js: ストリーム処理
const fs = require('fs');
const { parse } = require('csv-parse');

fs.createReadStream('data.csv')
  .pipe(parse({ columns: true }))
  .on('data', (row) => console.log(row))
  .on('end', () => console.log('完了'));

fast-csv — Node.js 専用の堅牢な選択肢

fast-csvNode.js 専用であり、ブラウザ環境での使用は想定されていません。TypeScript との親和性が高く、スキーマバリデーションやデータ変換機能が充実しています。

// Node.js: Promise ベース
const fs = require('fs');
const csv = require('fast-csv');

const rows = await csv.parseString(fs.readFileSync('data.csv', 'utf8'), { headers: true }).toArray();
console.log(rows);

csv-parser — 非推奨のストリーム専用ライブラリ

csv-parser は Node.js のストリーム API に特化していましたが、非推奨のため新規プロジェクトでの使用は避けてください

// 非推奨の例(参考のみ)
fs.createReadStream('data.csv')
  .pipe(csv())
  .on('data', (row) => console.log(row));

🧩 API スタイル:ストリーム vs Promise vs コールバック

ストリーム処理が必要?

  • csv-parse: stream().pipe(parse()) 形式で完全対応
  • fast-csv: parseStream() でストリーム対応
  • papaparse: ストリーム非対応(代わりに chunked parsing で擬似ストリーム処理)
  • csv-parser: ストリーム専用(非推奨)
// csv-parse: ストリーム
const parser = parse({ columns: true });
readableStream.pipe(parser);

// fast-csv: ストリーム
const stream = csv.parseStream(readableStream, { headers: true });

// papaparse: チャンク処理(ストリーム風)
Papa.parse(file, {
  step: (row) => console.log(row.data), // 行ごとにコールバック
  complete: () => console.log('終了')
});

Promise を使いたい?

  • papaparse: download: true 時を除き、基本はコールバック。Promise 化は自前でラップ必要
  • csv-parse: parse() 関数で Promise 対応(v5+)
  • fast-csv: .toArray() で Promise 対応
// csv-parse: Promise
const records = await parse(csvString, { columns: true });

// fast-csv: Promise
const records = await csv.parseString(csvString, { headers: true }).toArray();

// papaparse: Promise 化(自前)
function parseCsv(file) {
  return new Promise((resolve, reject) => {
    Papa.parse(file, {
      header: true,
      complete: resolve,
      error: reject
    });
  });
}

🛠️ 機能比較:ヘッダー、カスタム区切り文字、エラーハンドリング

ヘッダー行の自動処理

全ライブラリが header: true 相当の機能を提供していますが、実装方法が異なります。

// papaparse
Papa.parse(csv, { header: true });

// csv-parse
parse(csv, { columns: true });

// fast-csv
csv.parseString(csv, { headers: true });

// csv-parser (非推奨)
csv({ headers: true });

カスタム区切り文字(例:タブ区切り)

// papaparse
Papa.parse(csv, { delimiter: '\t' });

// csv-parse
parse(csv, { delimiter: '\t' });

// fast-csv
csv.parseString(csv, { delimiter: '\t' });

// csv-parser (非推奨)
csv({ separator: '\t' });

エラーハンドリング

  • papaparse: error コールバックで詳細なエラー情報(行番号、タイプ)を提供
  • csv-parse: on('error', ...) または Promise の catch
  • fast-csv: エラーイベントまたは Promise の reject
// papaparse
Papa.parse(csv, {
  error: (error, file) => console.error('行', error.row, ':', error.message)
});

📦 バンドルサイズと依存関係

  • papaparse: 軽量(~15KB minified)、依存なし、Tree-shaking 可能
  • csv-parse: 中程度(~30KB+)、Node.js 由来の依存あり
  • fast-csv: やや重め(複数サブパッケージ)、TypeScript 型定義込み
  • csv-parser: 軽量だが非推奨

フロントエンドアプリでは、バンドルサイズと初期ロード時間が重要です。papaparse はこの点で優れています。

🎯 ユースケース別:どのライブラリを選ぶべきか?

ケース1: Web アプリで CSV アップロード機能を実装

papaparse が最適

  • File API と直接連携
  • プログレス表示やキャンセル可能
  • Web Worker で UI ブロッキング回避
// 実際のアップロード処理
const handleFile = (file) => {
  Papa.parse(file, {
    header: true,
    worker: true, // Web Worker で実行
    step: (row) => updatePreview(row.data),
    complete: () => showSuccess()
  });
};

ケース2: Node.js で大規模 CSV をストリーム処理

csv-parse または fast-csv

  • メモリ使用量を抑えて処理可能
  • fast-csv は TypeScript と相性が良い
// csv-parse でのストリーム処理
fs.createReadStream('huge.csv')
  .pipe(parse({ columns: true }))
  .pipe(transformData())
  .pipe(writeToDB());

ケース3: 小規模 CSV を同期的にパース

papaparse(ブラウザ)または csv-parse(Node.js)

  • 単純な文字列パースならどちらも十分
// ブラウザ(同期)
const result = Papa.parse(csvString, { header: true });

// Node.js(同期)
const records = parse(csvString, { columns: true });

📊 まとめ:選定の判断基準

条件推奨ライブラリ
ブラウザで CSV アップロードpapaparse
Node.js でストリーム処理csv-parse または fast-csv
TypeScript と連携fast-csv
軽量で依存なしpapaparse
非推奨を避けるcsv-parser は使用しない

💡 最終アドバイス

  • フロントエンド開発者はまず papaparse を試してください。使いやすく、機能も十分です。
  • Node.js バックエンドで大量データを扱うなら、csv-parse の安定性か fast-csv の型安全性から選んでください。
  • csv-parser は新規プロジェクトで使用しないでください。非推奨のため、セキュリティやバグ修正が保証されません。

CSV パースは一見単純に見えますが、実際には改行、クォート、エンコーディング、不正データなど、多くの落とし穴があります。信頼できるライブラリを選ぶことで、こうした問題を効率的に回避できます。

選び方: csv-parse vs csv-parser vs fast-csv vs papaparse

  • csv-parse:

    csv-parse は Node.js 向けの高機能かつ安定した CSV パーサーで、ストリーム処理と同期/非同期 API の両方をサポートしています。Node.js バックエンドで大量の CSV を処理する必要がある場合や、細かいパース設定(区切り文字、クォート、コメント行など)を制御したい場合に最適です。ただし、ブラウザ環境ではバンドルサイズや互換性の観点から注意が必要です。

  • csv-parser:

    csv-parser は Node.js のストリーム API に特化したシンプルな CSV パーサーです。fs.createReadStream() と組み合わせて大規模ファイルをメモリ効率よく処理するシナリオに向いています。ただし、2023年時点で公式 npm ページに「メンテナンスされていない可能性がある」との注意書きがあり、新規プロジェクトでは代替手段の検討を強く推奨します。

  • fast-csv:

    fast-csv は Node.js 向けの CSV パース・生成ライブラリで、ストリームと Promise の両方のインターフェースを提供します。型安全性(TypeScript 対応)や柔軟なスキーマ定義、データ変換機能が特徴です。Node.js 環境で堅牢かつ拡張性の高い CSV 処理が必要な場合に適していますが、ブラウザ向けの使用は想定されていません。

  • papaparse:

    papaparse はブラウザと Node.js の両方で動作する軽量で高速な CSV パーサーです。特にフロントエンド開発において、File API や Blob からの直接パース、プログレス表示、ワーカーによる非同期処理など、ユーザー体験を考慮した機能が充実しています。Web アプリで CSV アップロード機能を実装するなら、まず最初に検討すべきライブラリです。

csv-parse のREADME

CSV parser for Node.js and the web

Build Status NPM NPM

The csv-parse package is a parser converting CSV text input into arrays or objects. It is part of the CSV project.

It implements the Node.js stream.Transform API. It also provides a simple callback-based API for convenience. It is both extremely easy to use and powerful. It was first released in 2010 and is used against big data sets by a large community.

Documentation

Main features

  • Flexible with lot of options
  • Multiple distributions: Node.js, Web, ECMAScript modules and CommonJS
  • Follow the Node.js streaming API
  • Simplicity with the optional callback API
  • Support delimiters, quotes, escape characters and comments
  • Line breaks discovery
  • Support big datasets
  • Complete test coverage and lot of samples for inspiration
  • No external dependencies
  • Work nicely with the csv-generate, stream-transform and csv-stringify packages
  • MIT License

Usage

Run npm install csv to install the full CSV module or run npm install csv-parse if you are only interested by the CSV parser.

Use the callback and sync APIs for simplicity or the stream based API for scalability.

Example

The API is available in multiple flavors. This example illustrates the stream API.

import assert from "assert";
import { parse } from "csv-parse";

const records = [];
// Initialize the parser
const parser = parse({
  delimiter: ":",
});
// Use the readable stream api to consume records
parser.on("readable", function () {
  let record;
  while ((record = parser.read()) !== null) {
    records.push(record);
  }
});
// Catch any error
parser.on("error", function (err) {
  console.error(err.message);
});
// Test that the parsed records matched the expected records
parser.on("end", function () {
  assert.deepStrictEqual(records, [
    ["root", "x", "0", "0", "root", "/root", "/bin/bash"],
    ["someone", "x", "1022", "1022", "", "/home/someone", "/bin/bash"],
  ]);
});
// Write data to the stream
parser.write("root:x:0:0:root:/root:/bin/bash\n");
parser.write("someone:x:1022:1022::/home/someone:/bin/bash\n");
// Close the readable stream
parser.end();

Contributors

The project is sponsored by Adaltas, an Big Data consulting firm based in Paris, France.