React hooks for CSV export with automatic pagination - drop the function, we handle the rest
npm install react-csv-autopilot




Drop the function, we handle the rest.
A React library for exporting large datasets to CSV with automatic pagination, streaming, and progress tracking. Built with Web Workers for non-blocking performance and File System Access API for efficient file writing.
---
- Automatic Pagination - Just provide a getNextPage function, we handle the rest
- Streaming Export - Uses ReadableStream for memory-efficient large file exports
- Non-blocking - Web Workers for CSV conversion without freezing the UI
- Progress Tracking - Real-time progress updates via BroadcastChannel
- TypeScript - Full type safety with TypeScript definitions
- Zero Dependencies - Only React as peer dependency
- Framework Agnostic Core - Use the core logic in any JavaScript environment
---
``bash`
npm install react-csv-autopilot
`bash`
yarn add react-csv-autopilot
`bash`
pnpm add react-csv-autopilot
---
`typescript
import { useExportCSV, useMessageExportCSV } from 'react-csv-autopilot';
function ExportButton() {
const { handler } = useExportCSV();
// Track export progress
useMessageExportCSV((progress) => {
if (progress.type === 'progress') {
console.log(${progress.loadedItemsCount}/${progress.total});
}
});
const handleExport = async () => {
await handler.execute({
fileName: 'users-export',
columns: [
{ key: 'id', label: 'ID' },
{ key: 'name', label: 'Full Name' },
{ key: 'email', label: 'Email Address' },
],
getNextPage: async (offset) => {
// Fetch your data - this will be called automatically
const response = await fetch(/api/users?page=${offset}&limit=100);
const data = await response.json();
return {
rows: data.users,
total: data.totalCount,
};
},
});
};
return ;
}
`
---
Hook that provides access to the CSV export controller.
Returns:
`typescript`
{
handler: ExportController // Controller instance for executing exports
}
Example:
`typescript
const { handler } = useExportCSV();
await handler.execute({
fileName: 'data-export',
columns: [...],
getNextPage: async (offset) => {...}
});
`
---
Hook for tracking export progress in real-time.
Parameters:
- callback: (payload: ExportProgressPayload) => void - Called on each progress updatechannelName?: string
- - Optional custom channel name (default: 'EXPORT_CSV_CHANNEL')
Payload Type:
`typescript`
type ExportProgressPayload = {
total: number;
loadedItemsCount: number;
type: 'progress' | 'done' | 'failed';
};
Example:
`typescript
const [progress, setProgress] = useState({ loaded: 0, total: 0 });
useMessageExportCSV((payload) => {
setProgress({
loaded: payload.loadedItemsCount,
total: payload.total,
});
if (payload.type === 'done') {
console.log('Export completed!');
}
});
`
---
#### ExportParams
`typescript`
type ExportParams = {
fileName: string;
columns: Column[];
getNextPage: (offset: number) => Promise<{ rows: any[]; total: number }>;
};
#### Column
`typescript`
type Column = {
key: string;
label: string;
timezone?: 'UTC' | string;
formatType?: 'dateFull' | 'dateMediumTime' | 'timeShort' | 'numDecimal' | 'numCompact' | 'numCurrency' | 'numPercent';
};
API with page numbers:
`typescript/api/data?page=${page}&size=100
getNextPage: async (offset) => {
const page = offset + 1; // Convert to 1-based pagination
const response = await fetch();`
return await response.json();
}
API with cursor-based pagination:
`typescript
let nextCursor = null;
getNextPage: async (offset) => {
const url = offset === 0
? '/api/data?limit=100'
: /api/data?cursor=${nextCursor}&limit=100;`
const response = await fetch(url);
const data = await response.json();
nextCursor = data.nextCursor;
return {
rows: data.items,
total: data.totalCount,
};
}
---
1. Stream-based Export - Uses ReadableStream and File System Access API for efficient file writinggetNextPage
2. Web Workers - CSV conversion happens in a separate thread to keep UI responsive
3. Automatic Pagination - Calls your function repeatedly until all data is fetchedBroadcastChannel
4. Progress Tracking - Uses to communicate progress across components
```
βββββββββββββββββββ
β React Hook β
β useExportCSV() β
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββ ββββββββββββββββ
β Export βββββββΆβ Web Worker β
β Controller β β (CSV Convert)β
ββββββββββ¬βββββββββ ββββββββββββββββ
β
βΌ
βββββββββββββββββββ ββββββββββββββββ
β ReadableStream βββββββΆβ File System β
β (Pagination) β β Access API β
βββββββββββββββββββ ββββββββββββββββ
---
Requires browsers with support for:
- File System Access API (Chrome 86+, Edge 86+)
- Web Workers (All modern browsers)
- ReadableStream (All modern browsers)
> Note: For browsers without File System Access API, the library will fall back to Blob-based download.
---
Contributions are welcome! Please feel free to submit a Pull Request.
---
MIT Β© Pavlo Kuzina
---
- npm Package: react-csv-autopilot
- Repository: GitHub - utils-kit
- Issues: GitHub Issues
- Monorepo: Part of utils-kit collection
---
- react-url-query-params - Type-safe URL query parameter management
---