This tutorial will guide you through using web-csv-toolbox's WebAssembly (WASM) acceleration to improve CSV parsing performance.
By the end of this tutorial, you'll be able to:
The library provides two entry points for WASM functionality. Choose based on your needs:
web-csv-toolbox) - Recommended for Most Usersimport { parseStringToArraySyncWASM } from 'web-csv-toolbox';
// Auto-initialization occurs on first WASM use.
// Optional but recommended: preload to reduce first‑parse latency
await loadWASM();
const records = parseStringToArraySyncWASM(csv);
Best for:
Characteristics:
loadWASM() is recommended to minimize first‑parse latencyweb-csv-toolbox/slim) - For Bundle Size Optimizationimport { loadWASM, parseStringToArraySyncWASM } from 'web-csv-toolbox/slim';
// Manual initialization required
await loadWASM();
const records = parseStringToArraySyncWASM(csv);
Best for:
Characteristics:
loadWASM() call required before using WASM featuresComparison:
| Aspect | Main | Slim |
|---|---|---|
| Bundle Size | Larger (WASM embedded) | Smaller (WASM external) |
| Initialization | Automatic | Manual |
| API Complexity | Simpler | Requires loadWASM() |
| Use Case | Convenience | Bundle optimization |
Note: This tutorial uses the main entry point (
web-csv-toolbox) for simplicity. To use the slim entry, simply import fromweb-csv-toolbox/slimand addawait loadWASM()before using WASM functions.
WebAssembly (WASM) is a binary instruction format that runs in modern browsers and runtimes. For CSV parsing, this means:
Note: Actual performance depends on many factors including CSV structure, file size, and runtime environment. See CodSpeed benchmarks for measured performance across different scenarios.
✅ Use WASM when:
") as quotation character❌ Skip WASM when:
') as quotation characterNote: WASM parser is stable but the implementation may change in future versions. For maximum stability, use the JavaScript parser (mainThread preset).
Load the module using loadWASM() once at application startup.
import { loadWASM } from 'web-csv-toolbox';
// Load WASM module (one-time initialization)
await loadWASM();
console.log('WASM module loaded');
Important: Call loadWASM() once at application startup, not before every parse operation. With the Main entry, this is optional but recommended.
Once loaded, use the engine option to enable WASM:
import { parse, loadWASM } from 'web-csv-toolbox';
// Load WASM (once)
await loadWASM();
const csv = `name,age,city
Alice,30,New York
Bob,25,San Francisco
Charlie,35,Los Angeles`;
// Parse using WASM
for await (const record of parse(csv, {
engine: { wasm: true }
})) {
console.log(record);
}
// { name: 'Alice', age: '30', city: 'New York' }
// { name: 'Bob', age: '25', city: 'San Francisco' }
// { name: 'Charlie', age: '35', city: 'Los Angeles' }
Instead of manual configuration, use predefined presets:
import { parse, loadWASM, EnginePresets } from 'web-csv-toolbox';
await loadWASM();
// Use 'fast' preset (main thread WASM)
for await (const record of parse(csv, {
engine: EnginePresets.fast()
})) {
console.log(record);
}
| Preset | Optimization Target | Worker | WASM | Stability |
|---|---|---|---|---|
fast |
Parse speed | ❌ | ✅ | ✅ Stable |
responsiveFast |
UI responsiveness + parse speed | ✅ | ✅ | ✅ Stable |
Note: For fastest execution time, use fast() on main thread. responsiveFast() prioritizes UI responsiveness with some worker communication overhead.
Combine WASM with Worker Threads for non-blocking UI with fast parsing:
import { parse, loadWASM, EnginePresets } from 'web-csv-toolbox';
await loadWASM();
// Use 'responsiveFast' preset (Worker + WASM)
for await (const record of parse(csv, {
engine: EnginePresets.responsiveFast()
})) {
console.log(record);
}
Benefits:
Note: This approach prioritizes UI responsiveness. Execution time may be slower than fast() on main thread due to worker communication cost, but UI remains responsive.
WASM works seamlessly with network fetching:
import { parseResponse, loadWASM, EnginePresets } from 'web-csv-toolbox';
await loadWASM();
async function fetchAndParseCSV(url: string) {
const response = await fetch(url);
for await (const record of parseResponse(response, {
engine: EnginePresets.responsiveFast()
})) {
console.log(record);
}
}
await fetchAndParseCSV('https://example.com/large-data.csv');
For special use cases, WASM provides a synchronous API:
import { parseStringToArraySyncWASM, loadWASM } from 'web-csv-toolbox';
await loadWASM();
const csv = `name,age
Alice,30
Bob,25`;
// Synchronous parsing (returns array)
const records = parseStringToArraySyncWASM(csv);
console.log(records);
// [
// { name: 'Alice', age: '30' },
// { name: 'Bob', age: '25' }
// ]
Use case: When you need all records immediately (not streaming)
⚠️ Warning: This loads the entire result into memory. Not suitable for large files.
WASM only supports UTF-8 encoding.
import { parse, loadWASM } from 'web-csv-toolbox';
await loadWASM();
// ✅ Works (UTF-8)
for await (const record of parse(csv, {
engine: { wasm: true }
})) {
console.log(record);
}
// ❌ Error (Shift-JIS not supported)
for await (const record of parse(shiftJISBinary, {
engine: { wasm: true },
charset: 'shift-jis'
})) {
console.log(record);
}
Workaround: Use JavaScript parser for non-UTF-8 encodings:
for await (const record of parse(shiftJISBinary, {
engine: { wasm: false }, // JavaScript parser
charset: 'shift-jis'
})) {
console.log(record);
}
WASM only supports double-quote (") as quotation character.
import { parse, loadWASM } from 'web-csv-toolbox';
await loadWASM();
// ✅ Works (double-quote)
for await (const record of parse(csv, {
engine: { wasm: true },
quotation: '"'
})) {
console.log(record);
}
// ❌ Error (single-quote not supported)
for await (const record of parse(csv, {
engine: { wasm: true },
quotation: "'"
})) {
console.log(record);
}
Workaround: Use JavaScript parser for single-quote CSVs:
for await (const record of parse(csv, {
engine: { wasm: false },
quotation: "'"
})) {
console.log(record);
}
If you forget to call loadWASM(), an error occurs:
import { parse } from 'web-csv-toolbox';
try {
// ❌ Forgot to call loadWASM()
for await (const record of parse(csv, {
engine: { wasm: true }
})) {
console.log(record);
}
} catch (error) {
console.error('WASM not loaded:', error);
}
Fix: Always call loadWASM() before parsing:
import { parse, loadWASM } from 'web-csv-toolbox';
await loadWASM(); // ✅ Load WASM first
for await (const record of parse(csv, {
engine: { wasm: true }
})) {
console.log(record);
}
import { parse, loadWASM } from 'web-csv-toolbox';
await loadWASM();
try {
// ❌ Single-quote not supported
for await (const record of parse(csv, {
engine: { wasm: true },
quotation: "'"
})) {
console.log(record);
}
} catch (error) {
console.error('Invalid quotation for WASM:', error.message);
// "Invalid quotation, must be double quote on WASM."
}
import { loadWASM } from 'web-csv-toolbox';
// Load WASM on page load
window.addEventListener('DOMContentLoaded', async () => {
try {
await loadWASM();
console.log('WASM ready');
} catch (error) {
console.error('WASM initialization failed:', error);
}
});
// Later in your code
async function handleFileUpload(file: File) {
const csv = await file.text();
for await (const record of parse(csv, {
engine: EnginePresets.responsiveFast()
})) {
console.log(record);
}
}
import { Hono } from 'hono';
import { loadWASM, parse, ReusableWorkerPool } from 'web-csv-toolbox';
const app = new Hono();
// Initialize WASM at server startup
await loadWASM();
console.log('WASM initialized');
// Create worker pool
using pool = new ReusableWorkerPool({ maxWorkers: 4 });
app.post('/parse-csv', async (c) => {
const csv = await c.req.text();
const results = [];
try {
for await (const record of parse(csv, {
engine: {
worker: true,
wasm: true,
workerPool: pool
}
})) {
results.push(record);
}
return c.json({ success: true, data: results });
} catch (error) {
return c.json({
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
}, 500);
}
});
export default app;
Performance Characteristics:
| Approach | Execution | UI Blocking | Characteristics |
|---|---|---|---|
| JavaScript (main thread) | Standard | ✅ Yes | Most stable, all encodings |
| WASM (main thread) | Compiled code | ✅ Yes | UTF-8 only, no worker overhead |
| Worker + WASM | Compiled code | ❌ No | UTF-8 only, worker communication overhead |
Note: Actual performance depends on many factors:
Recommendation: Benchmark your specific use case to determine the best approach. See CodSpeed for measured performance across different scenarios.
WASM is supported across all modern browsers:
| Browser | WASM Support | Notes |
|---|---|---|
| Chrome | ✅ | Full support |
| Firefox | ✅ | Full support |
| Edge | ✅ | Full support |
| Safari | ✅ | Full support |
Browser API Support:
For detailed browser compatibility, see Supported Environments.
You've learned how to:
loadWASM()Problem: Error: "WASM failed to load"
Solution:
Problem: WASM is slower than JavaScript
Solution:
EnginePresets.fast() on the main thread (blocks UI)loadWASM() once at startup to avoid repeated initialization overhead (auto-initialization works but adds latency on first use)Problem: Incorrect characters in parsed data
Solution:
{ engine: { wasm: false } }For complete, working examples using WASM with different entry points:
Need help? Open an issue on GitHub.