Tool for exporting data to a format that can be used for reporting such as CSV, JSON, etc.
npm install @scottluskcis/export-toolkit> Tool for exporting data to a format that can be used for reporting such as CSV, JSON, etc.






- ๐ Fluent Builder API - Intuitive, chainable configuration
- ๐ CSV & JSON Support - Export to popular formats
- ๐ Async Generator Streaming - Handle large datasets efficiently
- ๐ช Lifecycle Hooks - Transform, validate, and track progress
- ๐ช Type-Safe - Full TypeScript support with strict typing
- โก High Performance - Automatic batching and memory optimization
- ๐ฏ Commander.js Integration - Perfect for CLI tools
- ๐งช Well-Tested - 170+ tests with 80%+ coverage
``bash`
npm install @scottluskcis/export-toolkitor
pnpm add @scottluskcis/export-toolkitor
yarn add @scottluskcis/export-toolkit
`typescript
import { outport } from '@scottluskcis/export-toolkit';
interface User {
id: number;
name: string;
email: string;
}
const users: User[] = [
{ id: 1, name: 'Alice', email: 'alice@example.com' },
{ id: 2, name: 'Bob', email: 'bob@example.com' },
];
// CSV export
await outport
// JSON export
await outport
`
`typescript`
// Tab-separated CSV with custom headers
await outport
.to('./users.tsv')
.withDelimiter('\t')
.withHeaders(['ID', 'Full Name', 'Email Address'])
.withUtf8Bom(true)
.write(users);
`typescriptProgress: ${current}/${total}
await outport
.to('./users.csv')
.onProgress((current, total) => {
console.log();`
})
.write(users);
`typescript
async function* fetchUsers(): AsyncGenerator
for (let page = 1; page <= 100; page++) {
const users = await api.getUsers(page);
for (const user of users) {
yield user;
}
}
}
// Automatically batched for efficiency
const result = await outport
.to('./users.csv')
.withBatchSize(100)
.onProgress((count) => console.log(Exported ${count} users...))
.fromAsyncGenerator(fetchUsers());
console.log(Total exported: ${result.value});`
`typescript
import { Command } from 'commander';
import { outport } from '@scottluskcis/export-toolkit';
const program = new Command();
program
.command('export')
.option('-o, --output
.action(async (options) => {
const users = await fetchUsers();
await outport
.to(options.output)
.onProgress((current, total) => {
process.stdout.write(\rExporting: ${current}/${total});\nโ Exported ${total} users
})
.onComplete((result, total) => {
if (result.success) {
console.log();`
}
})
.write(users);
});
- Builder API Guide - Complete guide to the fluent builder API
- CSV Writer Guide - CSV-specific examples and patterns
- JSON Writer Guide - JSON-specific examples and patterns
- Type Safety Examples - TypeScript usage patterns
The fluent builder API makes configuration intuitive and self-documenting:
`typescript`
await outport
.to('./users.csv') // Where to write
.withDelimiter(',') // CSV config
.withHeaders(['ID', 'Name']) // Custom headers
.onProgress(trackProgress) // Lifecycle hooks
.write(users); // Execute
Tap into the export process at key points:
`typescript`
await outport
.to('./users.csv')
.onBeforeWrite((data) => data.filter((u) => u.active)) // Transform
.onProgress((current, total) => updateUI(current)) // Track
.onAfterWrite((data, count) => logExport(count)) // Post-process
.onError((error) => handleError(error)) // Error handling
.onComplete((result, total) => notify(total)) // Completion
.write(users);
Process millions of records without loading them all into memory:
`typescript
async function* streamFromDatabase() {
let offset = 0;
const batchSize = 1000;
while (true) {
const records = await db.query({ offset, limit: batchSize });
if (records.length === 0) break;
for (const record of records) {
yield record;
}
offset += batchSize;
}
}
// Automatically batched and memory-efficient
await outport
.to('./records.csv')
.withBatchSize(500)
.fromAsyncGenerator(streamFromDatabase());
`
Outport follows SOLID principles and clean architecture:
- Single Responsibility: Each class has one job (formatting, writing, batching)
- Open/Closed: Extend with hooks without modifying core code
- Liskov Substitution: All writers implement the same interface
- Interface Segregation: Separate interfaces for different concerns
- Dependency Inversion: Depend on abstractions, not concretions
``
Builder API (Fluent Interface)
โ
WriterFactory (Abstraction)
โ
โโโ CsvWriter โโโ CsvFormatter, CsvHeaderManager
โโโ JsonWriter โโโ JsonFormatter
โ
FileWriter (I/O Abstraction)
โ
Node.js File System
`bashClone the repository
git clone https://github.com/scottluskcis/export-toolkit.git
cd export-toolkit
$3
| Script | Description |
| ------------------------ | -------------------------------------------------------- |
|
pnpm run build | Compile TypeScript to JavaScript |
| pnpm run test | Run tests once |
| pnpm run test:watch | Run tests in watch mode |
| pnpm run test:coverage | Generate test coverage report |
| pnpm run lint | Check for linting errors |
| pnpm run lint:fix | Fix auto-fixable linting errors |
| pnpm run format | Format all files with Prettier |
| pnpm run format:check | Check if files are formatted correctly |
| pnpm run typecheck | Type check without emitting files |
| pnpm run ci | Run all CI checks (typecheck, lint, format, build, test) |$3
`
export-toolkit/
โโโ .github/ # GitHub Actions workflows and configs
โโโ docs/ # Documentation
โ โโโ csv-writer.md # CSV Writer usage guide
โโโ src/ # Source TypeScript files
โ โโโ index.ts # Main entry point
โ โโโ index.test.ts # Test files
โโโ dist/ # Compiled JavaScript (generated)
โโโ coverage/ # Test coverage reports (generated)
โโโ .nvmrc # Node.js version specification
โโโ package.json # Project metadata and dependencies
โโโ tsconfig.json # TypeScript configuration
โโโ vitest.config.ts # Vitest test configuration
โโโ eslint.config.js # ESLint configuration (flat config)
โโโ .prettierrc # Prettier configuration
`๐ Documentation
- CSV Writer Guide - Examples and usage patterns for the CSV writer
- JSON Writer Guide - Examples and usage patterns for the JSON writer
๐งช Testing
This project uses Vitest for testing with the following features:
- โ
Global test APIs (describe, it, expect)
- ๐ Coverage reports with v8
- โก Fast execution with Vite
- ๐ฏ 80%+ coverage threshold
Run tests:
`bash
Run once
pnpm run testWatch mode
pnpm run test:watchWith coverage
pnpm run test:coverage
`๐จ Code Quality
- TypeScript: Strict mode with modern ES2022+ features
- ESLint: v9+ with flat config and TypeScript support
- Prettier: Consistent code formatting
- Vitest: Comprehensive test coverage
- Husky: Pre-commit hooks for quality checks
๐ค Contributing
Contributions are welcome! Please follow these steps:
1. Fork the repository
2. Create a feature branch (
git checkout -b feature/amazing-feature)
3. Write tests for your changes
4. Make your changes
5. Ensure all checks pass (pnpm run ci)
6. Commit your changes (git commit -m 'Add amazing feature')
7. Push to the branch (git push origin feature/amazing-feature`)Please make sure to:
- Write tests for new functionality
- Follow the existing code style
- Update documentation as needed
- Ensure all CI checks pass
MIT ยฉ scottluskcis