mrkeyoor.com_
Sun 20 Sept 11:42 UTC
npmDataupdated 20 Sept 2026

csv-parse review

csv-parse 7.0.2 reads delimited text through a Node Transform stream, a callback, or a separate synchronous entry. It understands quoted line breaks, byte-order marks, comments, alternate separators, duplicate columns, casting hooks, record filters, and parse-location metadata. Version 7 introduced automatic delimiter detection and exported CsvError; 7.0.2 prevents column names from replacing an object's prototype and cuts a buffer allocation. This package stops at parsing. It does not read Excel workbooks or prove that a row matches a business schema. Our ordinary browser build failed because the main entry follows Node stream code.

Verdict

csv-parse 7.0.2 installed in 0.6 seconds as one 2 MB package with no audit findings in our sandbox, while its normal browser bundle failed. Install it for messy or unbounded CSV on Node; choose a browser-first parser, workbook library, or schema validator when that is the actual job.

We installed it

Lab card: what happened when we installed csv-parseScreenshot of csv-parse documentation
Install✓ · 0.6s1 package on disk · 2 MB
ImportESM import works · require() works · ESM package with exports map
Browsern/acould not be bundled for the browser (Node-only code, most likely)
TypesTypeScript types bundled
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does csv-parse install cleanly?

Yes. In a fresh container with an empty cache, npm install csv-parse finished in 0.6s, leaving 1 package and 2 MB on disk. npm audit reported no known vulnerabilities.

Can csv-parse run in a browser?

Not directly: esbuild could not bundle it for the browser in our run, which normally means it depends on Node built-ins. Use it on the server, or find a browser-targeted alternative.

Does csv-parse work with both ESM and CommonJS?

Yes. Both import 'csv-parse' and require('csv-parse') worked in Node 22 in our run. The package is published as ESM with an exports map.

Does csv-parse include TypeScript types?

Yes, type declarations ship inside the package, so no @types install is needed.

csv-parse or papaparse: which should you use?

papaparse: Choose it for browser uploads, workers, progress callbacks, and a UI-led parsing flow. csv-parse 7.0.2 installed in 0.6 seconds as one 2 MB package with no audit findings in our sandbox, while its normal browser bundle failed.

When should you not use csv-parse?

The source is XLSX and its formulas, sheets, or cell types matter. CSV has no representation for those workbook features.

API stability4/5Version 7.0.2 still supports the established Transform stream, callback, sync, and async-iterator usage, and most behavior is selected through named options. Version 6 renamed some options and error codes, so code that branches on CsvError.code needs upgrade tests. Version 7 was published as a major even though its release note described no intended breaking changes, which makes the project's major-version signal less dependable than the API itself.
Docs5/5The parse-specific site documents the stream, callback, sync, and async-iterator forms and gives individual pages to its many options. Examples cover BOM removal, casting context, duplicate headers, bad column counts, record information, comments, and errors. The repository README describes all five monorepo packages rather than teaching this parser, so https://csv.js.org/parse/ is the useful starting point for 7.x behavior.
Maintenance5/5csv-parse 7.0.2 was published on August 2, 2026, the repository was pushed on August 5, and GitHub showed 50 open issues and pull requests. That patch closes a prototype replacement path through column-derived object keys and reduces buffer allocation. The unarchived monorepo maintains parser, stringifier, generator, and transform packages together, with package-level change notes that identify which part changed.
Ecosystem4/5npm counted 18,786,158 downloads from August 19 through 25, 2026, and GitHub reported 4,283 stars. The surrounding Node CSV project supplies matching generation, transformation, and stringification packages. CommonJS and ESM consumers both loaded the current parser in our sandbox, but browser-oriented upload tooling is better served by Papa Parse and workbook input requires a different data model entirely.

Use it if

  • A multi-gigabyte import must yield records under Node stream backpressure instead of collecting the file in memory.
  • Supplier files contain quoted newlines, comments, BOMs, unusual delimiters, or inconsistent record widths.
  • Import errors need line, byte, header, and record context that can be shown back to the file owner.
  • One codebase needs a synchronous helper for bounded fixtures and an async iterator for production files.
Skip it if

Setup reality

We installed csv-parse 7.0.2 in a clean Node 22 Bookworm sandbox. npm completed in 0.6 seconds, leaving one package and 2 MB on disk. The package was 1,684 KB unpacked with 0 direct dependencies and 0 peers. Its TypeScript declarations are included. npm audit found 0 known vulnerabilities. Although package.json marks it as ESM and defines exports, both require() and ESM import worked in our checks.

No service account, secret, or project config is needed. Choose the API based on the input ceiling: csv-parse/sync retains every record, and the callback API also returns a complete array. For files that can grow, pipe createReadStream() into parse() and consume the parser with for await. Awaiting database work inside that loop lets stream backpressure limit queued records.

columns: true turns the first row into object keys. Set bom: true when UTF-8 files may begin with a marker, or the marker becomes part of the first header. A cast callback also receives header cells, so check context.header before converting quantities or dates. Treat its output as untrusted data and validate each record before a write.

The default behavior stops on malformed CSV. If policy allows skipped or ragged rows, attach on_skip and return rejection counts with the import result. Physical lines and logical records diverge when a quoted cell contains a newline. Version 7.0.2 blocks a prototype replacement route through column names, but downstream code should still whitelist fields. Our browser-targeted esbuild attempt failed, so use the documented browser entry deliberately rather than importing the Node stream path.

Patterns

Parse a bounded CSV string parse-bounded-text

import { parse } from 'csv-parse/sync';

const records = parse(text, {
  columns: true,
  bom: true,
  skip_empty_lines: true,
});

The sync entry holds all records and throws at the first parse error, so give it input with a known size limit.

Consume a file with backpressure stream-file-records

import { createReadStream } from 'node:fs';
import { parse } from 'csv-parse';

const rows = createReadStream('orders.csv').pipe(parse({ columns: true, bom: true }));
for await (const row of rows) await storeOrder(row);

Awaiting each store operation slows the source. Catch errors around the loop because malformed input rejects the stream.

Detect a delimiter discover-separator

const records = parse(text, {
  delimiter_auto: true,
  delimiter_auto_sample: 32 * 1024,
  columns: true,
});

Version 7 added delimiter discovery. Reject a detected separator that your import contract does not permit.

Convert selected values cast-one-column

const parser = parse({
  columns: true,
  cast(value, context) {
    if (context.header) return value;
    return context.column === 'quantity' ? Number(value) : value;
  },
});

cast runs for headers too. Check for NaN and validate the completed record separately.

Keep evidence for rejected rows audit-skipped-rows

const rejected = [];
const parser = parse({
  columns: true,
  skip_records_with_error: true,
  on_skip(error, raw) { rejected.push({ code: error.code, line: error.lines, raw }); },
});

A skipped record is data loss unless the importer reports it. Set an acceptable rejection limit outside the parser.

Group repeated column names preserve-duplicate-headers

const records = parse(text, {
  columns: true,
  group_columns_by_name: true,
});

Repeated names become arrays only with group_columns_by_name; otherwise a later value replaces the earlier one.

Filter and map during parsing reshape-each-record

const parser = parse({
  columns: true,
  on_record(row, info) {
    if (!row.email) return null;
    return { email: row.email.trim().toLowerCase(), sourceLine: info.lines };
  },
});

Returning null removes a record. Keep network and database calls outside this synchronous parsing hook.

Attach parse positions emit-location-info

const parser = parse({ columns: true, info: true });
for await (const item of parser) {
  console.log(item.info.lines, item.info.bytes, item.record);
}

info: true wraps each record, changing the emitted shape expected by downstream consumers.

Collect records with a callback parse-with-callback

parse(text, { columns: true }, (error, records, info) => {
  if (error) return finish(error);
  console.log(records.length, info.lines);
  finish();
});

The callback receives the complete array, so its memory profile suits bounded input rather than open-ended files.

Ignore comments and empty records handle-comment-lines

const parser = parse({
  columns: true,
  comment: '#',
  comment_no_infix: true,
  skip_empty_lines: true,
  skip_records_with_empty_values: true,
});

comment_no_infix recognizes comments only at line starts, preserving hash characters inside ordinary fields.

Select a logical record range read-record-window

const records = parse(text, { columns: true, from: 51, to: 100 });

from and to count records. The from_line and to_line options count physical lines, which differ when cells contain newlines.

Branch on a CSV error code classify-parser-error

import { CsvError, parse } from 'csv-parse/sync';

try {
  parse(text, { columns: true });
} catch (error) {
  if (error instanceof CsvError) console.error(error.code, error.lines);
  else throw error;
}

Use CsvError.code instead of matching messages. Major releases have renamed codes, so cover this policy with tests.

Alternatives

PackageRegistryPick it when
papaparsenpmChoose it for browser uploads, workers, progress callbacks, and a UI-led parsing flow.
fast-csvnpmChoose it when Node stream parsing and formatting should come from one project.
csv-parsernpmChoose it for a narrower Node stream parser with fewer switches.

More data guides

numpy · fsspec · pandas · sqlalchemy · pyarrow · lxml · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.