> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ooneex.com/llms.txt
> Use this file to discover all available pages before exploring further.

# CSV

> Stream rows from CSV files and convert them to JSON or YAML, powered by Bun's file APIs.

`@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.

```bash theme={null}
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.

```typescript theme={null}
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`).

```typescript theme={null}
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.

```typescript theme={null}
// 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.

```typescript theme={null}
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.

```typescript theme={null}
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.
