wasm-csv-parser
v1.1.0
Published
High-performance CSV parsing powered by Rust and WebAssembly
Maintainers
Readme
wasm-csv-parser
High-performance CSV parsing powered by Rust and WebAssembly.
wasm-csv-parser is a CSV parsing library that leverages Rust compiled to WebAssembly for near-native performance in JavaScript/TypeScript environments. It supports SIMD acceleration via Rayon, streaming parsing for large files, and handles datasets up to 500MB.
Features
- Rust + WebAssembly — native-speed parsing in the browser and Node.js/Bun
- Streaming API — process large CSV files without loading everything into memory
- Parallel processing — Rayon-based parallelism for unquoted CSV data
- TypeScript support — ships with full type definitions
- Configurable — custom delimiters and quote characters
Installation
bun add wasm-csv-parserQuick Start
Streaming API (TypeScript)
Parse a CSV file as a stream — rows are yielded one at a time via an async generator:
import { parseCSV, createReadableStreamFromFile } from 'wasm-csv-parser';
const stream = createReadableStreamFromFile('data.csv');
for await (const row of parseCSV(stream)) {
console.log(row); // ["Alice", "30", "Berlin"]
}Or from a string:
import { parseCSV, createReadableStreamFromString } from 'wasm-csv-parser';
const stream = createReadableStreamFromString('name,age,city\nAlice,30,Berlin\nBob,25,Munich');
for await (const row of parseCSV(stream, { header: true })) {
console.log(row);
}
// ["name", "age", "city"]
// ["Alice", "30", "Berlin"]
// ["Bob", "25", "Munich"]WASM Direct API
For synchronous, in-memory parsing powered by Rust/WebAssembly:
import { parse_csv } from 'wasm-csv-parser/wasm';
const rows = parse_csv('name,age,city\nAlice,30,Berlin\nBob,25,Munich', ',', '"');
console.log(rows);
// [["name", "age", "city"], ["Alice", "30", "Berlin"], ["Bob", "25", "Munich"]]API Reference
The package exposes two entry points:
| Import path | Description |
|---|---|
| wasm-csv-parser | Pure TypeScript streaming parser (parseCSV, csvToJSON, createReadableStreamFromFile, etc.) |
| wasm-csv-parser/wasm | Rust-compiled WASM parser (parse_csv, parse_csv_stream) |
wasm-csv-parser — TypeScript Streaming API
parseCSV(stream, options?)
Async generator that yields each row as string[].
import { parseCSV, createReadableStreamFromFile } from 'wasm-csv-parser';
const stream = createReadableStreamFromFile('data.csv');
for await (const row of parseCSV(stream, { header: true })) {
console.log(row);
}Options:
| Option | Type | Default | Description |
|---|---|---|---|
| header | boolean | true | Whether to yield the header row |
| delimiter | string | "," | Field delimiter |
| quote | string | '"' | Quote character |
csvToJSON(stream, options)
Async generator that yields typed objects using a custom transform function:
import { csvToJSON, createReadableStreamFromString } from 'wasm-csv-parser';
const stream = createReadableStreamFromString('name,age,city\nAlice,30,Berlin\nBob,25,Munich');
const transform = (header: string[], row: string[]): Record<string, string> => {
const obj: Record<string, string> = {};
header.forEach((key, idx) => { obj[key] = row[idx]; });
return obj;
};
for await (const json of csvToJSON(stream, { transform })) {
console.log(json);
}
// { name: "Alice", age: "30", city: "Berlin" }
// { name: "Bob", age: "25", city: "Munich" }createReadableStreamFromFile(path)
Creates a ReadableStream from a file path (Node.js / Bun only):
import { createReadableStreamFromFile } from 'wasm-csv-parser';
const stream = createReadableStreamFromFile('data.csv');createReadableStreamFromString(input)
Creates a ReadableStream from a string (works in any environment):
import { createReadableStreamFromString } from 'wasm-csv-parser';
const stream = createReadableStreamFromString('a,b,c\n1,2,3');parseRow(line, options?)
Parses a single CSV line into an array of field values:
import { parseRow } from 'wasm-csv-parser';
parseRow('Alice,30,Berlin'); // ["Alice", "30", "Berlin"]
parseRow('Alice;30;Berlin', { delimiter: ';' }); // ["Alice", "30", "Berlin"]readLine(stream, options?)
Async generator that yields individual lines from a ReadableStream, handling quoted fields and CRLF:
import { readLine, createReadableStreamFromString } from 'wasm-csv-parser';
const stream = createReadableStreamFromString('line1\nline2\nline3');
for await (const line of readLine(stream)) {
console.log(line);
}wasm-csv-parser/wasm — Rust/WASM API
parse_csv(input, delimiter?, quote?)
Synchronously parses the full CSV string and returns all rows as string[][]:
import { parse_csv } from 'wasm-csv-parser/wasm';
const rows = parse_csv('name,age,city\nAlice,30,Berlin\nBob,25,Munich', ',', '"');
console.log(rows[0]); // ["name", "age", "city"]
console.log(rows[1]); // ["Alice", "30", "Berlin"]
// Access individual fields by index
const city = rows[1][2]; // "Berlin"To map rows to objects using the header:
const [header, ...data] = parse_csv(csvString, ',', '"');
const records = data.map((row) =>
Object.fromEntries(header.map((key, i) => [key, row[i]]))
);
// [{ name: "Alice", age: "30", city: "Berlin" }, ...]parse_csv_stream(input, delimiter, quote, callback)
Parses CSV row-by-row, invoking a callback for each row:
import { parse_csv_stream } from 'wasm-csv-parser/wasm';
parse_csv_stream('name,age,city\nAlice,30,Berlin\nBob,25,Munich', ',', '"', (row) => {
console.log('Parsed row:', row);
});| Parameter | Description |
| ----------- | ------------------------------------------------ |
| input | CSV data as a string |
| delimiter | Field delimiter (e.g. ",") or null for default |
| quote | Quote character (e.g. '"') or null for default |
| callback | Invoked per parsed row with an array of field values |
Typed Row Mapping
Create a reusable mapping function to get typed objects from raw rows:
import { parse_csv } from 'wasm-csv-parser/wasm';
interface User {
name: string;
age: number;
city: string;
}
function mapCsv<T>(rows: string[][], mapRow: (row: string[]) => T): T[] {
const [, ...data] = rows; // skip header
return data.map(mapRow);
}
const rows = parse_csv(csvString, ',', '"');
const users = mapCsv<User>(rows, ([name, age, city]) => ({
name,
age: Number(age),
city,
}));
// users: User[] — fully typed
console.log(users[0].name); // "Alice"
console.log(users[0].age); // 30 (number, not string)Development
Build
Compile Rust to WebAssembly and bundle the TypeScript layer:
bun run build # full build (wasm + ts)
bun run build:wasm # wasm-pack only
bun run build:ts # pkgroll onlyTest
bun run test # Rust unit tests (cargo test)
bun run test:ts # TypeScript tests (vitest)Architecture
JavaScript / TypeScript Layer
The TS streaming implementation (src/ts/) provides parseCSV, csvToJSON, createReadableStreamFromFile, createReadableStreamFromString, readLine, and helpers — bundled with pkgroll. The WASM glue layer (pkg/) is generated by wasm-pack and shipped pre-compiled.
Rust Core
The parsing engine is implemented in Rust for performance and memory safety. Key modules:
csv.rs— core parsing logic with a state-machine based parser for quoted fieldsstream.rs— streaming row-by-row processinglib.rs—wasm-bindgenbindings exposing the public API to JavaScript
Performance
- Unquoted CSV: parallel line processing via Rayon (
par_bridge()) - Quoted CSV: incremental state-machine parser with minimal peak memory usage
- WASM layer: tuned for low overhead; chunk-based processing integrates with JavaScript streaming APIs
License
MIT © Aron Homberg, 2025–2026
