Skip to main content
@ooneex/csv is a small, streaming CSV reader built on top of Bun. It parses CSV files line by line into typed records, handles quoted fields and custom separators, lets you skip rows by pattern, and can convert a file directly to JSON or YAML without loading everything into memory.

Installation

Add the package with Bun.
bun add @ooneex/csv

Usage

Create a Csv instance with a file path and iterate rows with the async generator load. The first row is treated as the header and each subsequent row becomes an object keyed by those headers. You can pass a type parameter for typed rows.
import { Csv } from "@ooneex/csv";

type User = {
  id: string;
  email: string;
  name: string;
};

const csv = new Csv<User>("./users.csv");

for await (const user of csv.load()) {
  console.log(user.email);
}
Pass a custom separator as the second constructor argument (,, ;, :, |, or \t).
const csv = new Csv<User>("./users.tsv", "\t");
Skip rows whose fields match a regular expression with the ignore option. Each key maps to a pattern, and matching rows are excluded from iteration.
// Skip internal accounts and empty emails.
for await (const user of csv.load({
  ignore: {
    email: /@internal\.test$|^$/,
  },
})) {
  console.log(user.name);
}
Convert a file straight to JSON or YAML. Both stream through the same parser and accept the same ignore filter.
const csv = new Csv<User>("./users.csv");

await csv.toJson({ path: "./users.json" });

await csv.toYaml({
  path: "./users.yaml",
  ignore: { email: /^$/ },
});
Missing files and read errors throw a CsvException you can catch and inspect.
import { Csv, CsvException } from "@ooneex/csv";

try {
  for await (const row of new Csv("./missing.csv").load()) {
    // ...
  }
} catch (error) {
  if (error instanceof CsvException) {
    console.error(error.message); // "CSV file not found: ./missing.csv"
  }
}

When to use it

  • You need to process large CSV files row by row without buffering the whole file in memory.
  • You want typed records out of a CSV with a header row, including support for quoted fields and escaped quotes.
  • You import data using non-comma separators (semicolon, tab, pipe, colon).
  • You need to filter out unwanted rows by pattern, or batch-convert CSV to JSON/YAML files.
  • You don’t need it for tiny, well-formed CSV strings you already have in memory, where a quick split is enough; this package targets file-based, streamed reading and requires the Bun runtime.