web-csv-toolbox - v0.14.0
    Preparing search index...

    Using WebAssembly for CSV Parsing

    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:

    • Understand when to use WebAssembly
    • Load and initialize the WASM module
    • Parse CSV using WASM acceleration
    • Combine WASM with Worker Threads for maximum performance
    • Handle WASM limitations and errors
    • Completed Getting Started tutorial
    • Node.js LTS or a modern browser
    • Basic understanding of async/await

    Choosing an Entry Point

    The library provides two entry points for WASM functionality. Choose based on your needs:

    Main Entry Point (web-csv-toolbox) - Recommended for Most Users

    import { 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:

    • ✅ Rapid prototyping and development
    • ✅ When you want the simplest API
    • ✅ Applications where bundle size is not critical

    Characteristics:

    • Automatic WASM initialization on first WASM use (not at import time)
    • Preloading via loadWASM() is recommended to minimize first‑parse latency
    • Larger bundle size (WASM embedded as base64)
    • ⚠️ Experimental auto-initialization may change in future

    Slim Entry Point (web-csv-toolbox/slim) - For Bundle Size Optimization

    import { loadWASM, parseStringToArraySyncWASM } from 'web-csv-toolbox/slim';

    // Manual initialization required
    await loadWASM();
    const records = parseStringToArraySyncWASM(csv);

    Best for:

    • ✅ Production applications with bundle size budgets
    • ✅ When optimizing initial load time
    • ✅ When you want explicit control over WASM loading

    Characteristics:

    • Manual loadWASM() call required before using WASM features
    • Smaller main bundle size (WASM external)
    • External WASM file for better caching

    Comparison:

    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 from web-csv-toolbox/slim and add await loadWASM() before using WASM functions.

    WebAssembly (WASM) is a binary instruction format that runs in modern browsers and runtimes. For CSV parsing, this means:

    • Compiled code execution using WASM instead of interpreted JavaScript
    • Potential performance benefits for CPU-intensive parsing
    • Same memory efficiency as JavaScript implementation

    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:

    • Parsing UTF-8 CSV files
    • Server-side parsing where blocking is acceptable
    • CSV uses standard delimiters (comma, tab, etc.)
    • CSV uses double-quote (") as quotation character

    ❌ Skip WASM when:

    • CSV uses non-UTF-8 encoding (Shift-JIS, EUC-JP, etc.)
    • CSV uses single-quote (') as quotation character
    • Stability is the highest priority (use JavaScript parser instead)
    • WASM initialization overhead matters for your use case

    Note: 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.

    • Main entry: Optional but recommended (reduces first‑parse latency)
    • Slim entry: Required before using any WASM features
    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:

    • ✅ Non-blocking UI (Worker Thread)
    • ✅ Fast parsing (compiled WASM code)
    • ⚠️ Worker communication adds overhead (data transfer between threads)

    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:

    • CSV structure and size
    • Runtime environment (Node.js, browser, Deno)
    • System capabilities
    • Worker communication overhead (when using workers)

    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:

    • ✅ Load the WASM module with loadWASM()
    • ✅ Parse CSV using WASM acceleration
    • ✅ Combine WASM with Worker Threads
    • ✅ Handle WASM limitations (UTF-8, double-quote only)
    • ✅ Initialize WASM in browser and server applications
    • ✅ Handle errors related to WASM

    Problem: Error: "WASM failed to load"

    Solution:

    • Ensure you're using a supported browser or runtime
    • Check network connectivity (WASM file may be loaded from CDN)
    • Verify bundler configuration (WASM file must be included)

    Problem: WASM is slower than JavaScript

    Solution:

    • WASM has initialization overhead - benchmark your specific use case
    • Worker + WASM adds worker communication overhead - may be slower than main thread WASM
    • For fastest execution time, use EnginePresets.fast() on the main thread (blocks UI)
    • For non-blocking UI, accept the worker communication overhead trade-off
    • Optionally call 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:

    • WASM only supports UTF-8
    • For other encodings (Shift-JIS, EUC-JP), use JavaScript parser with { engine: { wasm: false } }

    For complete, working examples using WASM with different entry points:


    Need help? Open an issue on GitHub.