High-performance CSV parser with SIMD acceleration

Built with Zig for native performance. Fast Mode now leads the benchmark suite for clean CSV data.

bun add turbocsv
177 MB/sFast Mode throughput
1.79xfaster than PapaParse
6.32xfaster than csv-parse

Performance Comparison

End-to-end benchmark including file reads on Apple Silicon. Clean generated CSV data. Higher is better.

Library1K rows10K rows100K rows
TurboCSV Fast Mode116.5 MB/s177.4 MB/s172.4 MB/s
PapaParse65.8 MB/s98.7 MB/s111.5 MB/s
TurboCSV Native42.5 MB/s53.0 MB/s57.6 MB/s
csv-parse25.1 MB/s35.1 MB/s33.3 MB/s
fast-csv22.7 MB/s33.5 MB/s32.6 MB/s

Fast Mode is optimized for simple CSV without quoted delimiters or multi-line fields. Run it yourself: bun run benchmark:compare

Features

SIMD Acceleration

ARM64 NEON and x86 SSE2 vector instructions for parallel character scanning at native speed.

Security & Validation

CSV injection protection, structured error reporting, skip bad rows, size limits, column relaxation.

DataFrame API

Pandas-like operations: select, filter, sort, groupBy, join with lazy evaluation.

Fast Mode

TypeScript-only parser for clean data. Dynamic typing, cast functions, nested JSON support.

22 CLI Flags

All parser options accessible via CLI: trim, comments, range processing, error handling, and more.

Memory-Mapped Files

Process files larger than RAM. Zero-copy parsing keeps data out of the JS heap.

RFC 4180 Compliant

Full support for quoted fields, escaped quotes, and multi-line values.

Cross-Platform

Native binaries for macOS, Linux, Windows. WASM fallback for universal compatibility.

What's New in v0.3.4

Current toolchain support, clearer benchmarks, and Fast Mode performance visibility.

Benchmark Clarity

  • bun run benchmark restored with generated sample files
  • benchmark:compare now reports native and Fast Mode separately
  • Benchmarks now time file reads for JavaScript parsers too
  • Fast Mode leads the simple CSV benchmark suite

Zig 0.16 Ready

  • Build script migrated to current module-level linking APIs
  • std.Io file APIs replace deprecated filesystem calls
  • DebugAllocator replaces the old general-purpose allocator
  • ArrayList usage updated for allocator-explicit methods

Runtime Polish

  • Row metadata now reuses parser header arrays instead of copying per row
  • Parallel parser synchronization updated for Zig 0.16
  • Focused unit tests can generate fixtures in clean checkouts
  • Native build and Zig test suite pass on the current toolchain

Previously in v0.3.0

Major feature release — 22 CLI flags, security hardening, Fast Mode, and robust error handling.

Security & Validation

  • CSV injection protection with escapeFormulae
  • Structured errors with type, code, row fields
  • skipRecordsWithError — silently drop malformed rows
  • maxRecordSize — reject oversized rows
  • Flexible column count handling (relax constraints)

Whitespace & Processing

  • trim, ltrim, rtrim — strip whitespace
  • Greedy empty row skipping with skipEmptyRows
  • fromLine / toLine — parse file ranges
  • Comment support with comments: true
  • Skip rows where all fields are empty

Fast Mode & Typing

  • Fast Mode — TypeScript-only parser for clean data
  • Dynamic typing — auto-convert to numbers/booleans
  • Cast functions — per-column type transformers
  • flatten() / unflatten() for nested JSON
  • unparse() with flattenObjects option

Advanced Features

  • Duplicate header handling (rename or error)
  • beforeFirstChunk — transform raw data
  • onRecord — per-record filtering/transform
  • Fixed SIMD quote handling bug
  • 22 CLI flags — all parser options available

Quick Start

import { CSVParser } from "turbocsv";

const parser = new CSVParser("data.csv");

for (const row of parser) {
  console.log(row.get("name"), row.get("email"));
}

parser.close();
import { CSVParser, unparse, flatten } from "turbocsv";

// Robust parsing with error handling
const parser = new CSVParser("messy.csv", {
  trim: true,                     // Clean whitespace
  skipRecordsWithError: true,     // Skip bad rows
  comments: true,                  // Skip # prefixed lines
  duplicateHeaders: "rename",      // Handle duplicate columns
  dynamicTyping: true,             // Auto-convert types
  maxRecordSize: 10000,            // Reject huge rows
  cast: {                          // Custom transformers
    price: (val) => parseFloat(val.replace("$", "")),
    date: (val) => new Date(val)
  }
});

// Process with structured error handling
for (const row of parser) {
  try {
    processRow(row);
  } catch (error) {
    if (error.code === "TooFewFields") {
      console.log(`Row ${error.row}: Missing fields`);
    }
  }
}

// Secure CSV output
const csv = unparse(data, {
  escapeFormulae: true,    // Prevent CSV injection
  flattenObjects: true     // Handle nested JSON
});
import { CSVParser } from "turbocsv";

const parser = new CSVParser("data.csv");
const df = parser.toDataFrame();

// Chain operations
const result = df
  .filter(row => row.age > 18)
  .select("name", "email", "age")
  .sorted("name", "asc")
  .first(100);

// Aggregation
const grouped = df.groupBy("department", [
  { col: "salary", fn: "mean" },
  { col: "id", fn: "count" },
]);

parser.close();
# Trim whitespace and skip bad rows
turbocsv head --trim --skip-errors data.csv

# Fast mode with dynamic typing
turbocsv head --fast --dynamic-typing --format json data.csv

# Run local benchmarks
bun run benchmark
bun run benchmark:compare

# Validate with structured error reporting
turbocsv validate data.csv
# Output: ERROR [TooFewFields] at row 42: Expected 5 fields, got 3

# Process specific range with comments
turbocsv head --from-line 5 --to-line 20 --comments data.csv

# Security: escape formula injection
turbocsv convert --escape-formulae data.csv -o safe.csv

# Handle duplicate headers
turbocsv head --duplicate-headers rename data.csv

See the full API documentation on GitHub.