Skip to content

Repository files navigation

WasmWorker Logo

WasmWorker

High-performance WebAssembly SDK for browser-based parallel computation.


🚀 Overview

WasmWorker is a lightweight SDK that lets developers run WebAssembly modules inside WebWorkers effortlessly.

It provides a clean API to offload CPU-heavy workloads off the main thread — combining native performance with JavaScript simplicity.


✨ Features

  • 🧩 Plug-and-play WebAssembly execution
  • Parallel processing via WebWorkers
  • 🔄 Typed message bridge between JS and WASM
  • 🌍 Works with Rust, Go, C/C++, or AssemblyScript modules
  • 🔒 Structured error handling with error codes
  • 🎯 TypeScript-first with full type safety
  • 🚀 Zero dependencies - lightweight and fast
  • 🔀 Concurrent calls with automatic request management

🧱 Quick Start

# Install with your favorite package manager
npm install @wasmworker/sdk
# or
pnpm add @wasmworker/sdk
import{WasmWorker}from'@wasmworker/sdk'// Load a WASM moduleconstworker=awaitWasmWorker.load({moduleUrl: '/path/to/module.wasm'})// Call WASM functions with type safetyconstresult=awaitworker.call<{a: number;b: number},number>('add',{a: 5,b: 3})console.log(result)// → 8// Clean up when doneworker.terminate()

📖 Documentation

API Reference

WasmWorker.load(options)

Load a WASM module in a new WebWorker.

staticasyncload(options: LoadOptions): Promise<WasmWorker>interfaceLoadOptions{moduleUrl: string;// URL to the WASM moduleinit?: Record<string,unknown>;// Optional import object}

worker.call(fn, payload?, options?)

Call a WASM function with optional payload.

asynccall<TIn=unknown,TOut=unknown>(fn: string,payload?: TIn,options?: CallOptions): Promise<TOut>interfaceCallOptions{transfer?: Transferable[];// Objects to transfer ownership}

worker.terminate()

Terminate the worker and clean up resources.

terminate(): void

Examples

Concurrent Calls

Run multiple WASM functions in parallel:

const[sum,product,difference]=awaitPromise.all([worker.call('add',{a: 10,b: 20}),worker.call('multiply',{a: 5,b: 6}),worker.call('subtract',{a: 100,b: 25})])console.log(sum,product,difference)// 30, 30, 75

Error Handling

Structured errors with codes for programmatic handling:

try{awaitworker.call('unknownFunction',{})}catch(error){console.error(error.code)// 'FN_NOT_FOUND'console.error(error.message)// "Function not found..."console.error(error.details)// { availableFunctions: [...] }}

With Transferables

Efficiently pass large buffers without copying:

constbuffer=newUint8Array(1024*1024)// 1MBconstresult=awaitworker.call('process',buffer,{transfer: [buffer.buffer]// Transfer ownership for zero-copy})

🧩 Example Use Cases

  • 🔢 Real-time analytics and data processing in the browser
  • 🖼️ Image and video processing without blocking UI
  • 🔐 Cryptographic operations and hashing
  • 🎮 Physics simulations and game engines
  • 🤖 AI model inference at the edge
  • 📊 Large dataset transformations

🔌 Framework Integration

Vanilla JavaScript/TypeScript

import{WasmWorker}from'@wasmworker/sdk';letworker: WasmWorker|null=null;asyncfunctioninitializeWorker(){worker=awaitWasmWorker.load({moduleUrl: '/path/to/module.wasm'});console.log('Worker initialized!');}asyncfunctionprocessData(input: number){if(!worker){thrownewError('Worker not initialized');}constresult=awaitworker.call('process',input);returnresult;}// Initialize on page loaddocument.addEventListener('DOMContentLoaded',()=>{initializeWorker().catch(console.error);});// Use in event handlersdocument.getElementById('btn')?.addEventListener('click',async()=>{constresult=awaitprocessData(42);document.getElementById('output')!.textContent=`Result: ${result}`;});

React

import{WasmWorker}from'@wasmworker/sdk';import{useState,useEffect,useCallback}from'react';// Custom hook for WasmWorkerfunctionuseWasmWorker(moduleUrl: string){const[worker,setWorker]=useState<WasmWorker|null>(null);const[loading,setLoading]=useState(true);const[error,setError]=useState<Error|null>(null);useEffect(()=>{letmounted=true;WasmWorker.load({ moduleUrl }).then((w)=>{if(mounted){setWorker(w);setLoading(false);}}).catch((err)=>{if(mounted){setError(err);setLoading(false);}});return()=>{mounted=false;worker?.terminate();};},[moduleUrl]);constcall=useCallback(async<TIn,TOut>(fn: string,payload?: TIn): Promise<TOut>=>{if(!worker)thrownewError('Worker not initialized');returnworker.call<TIn,TOut>(fn,payload);},[worker]);return{ worker, loading, error, call };}// Component exampleexportfunctionWasmComponent(){const{ loading, error, call }=useWasmWorker('/module.wasm');const[result,setResult]=useState<number|null>(null);consthandleProcess=async()=>{try{constoutput=awaitcall<number,number>('process',42);setResult(output);}catch(err){console.error('Processing failed:',err);}};if(loading)return<div>LoadingWASM module...</div>;if(error)return<div>Error: {error.message}</div>;return(<div><buttononClick={handleProcess}>ProcessData</button>{result!==null&&<p>Result: {result}</p>}</div>);}

Vue 3

import{WasmWorker}from'@wasmworker/sdk';import{ref,onMounted,onUnmounted}from'vue';exportfunctionuseWasmWorker(moduleUrl: string){constworker=ref<WasmWorker|null>(null);constloading=ref(true);consterror=ref<Error|null>(null);onMounted(async()=>{try{worker.value=awaitWasmWorker.load({ moduleUrl });loading.value=false;}catch(err){error.value=errasError;loading.value=false;}});onUnmounted(()=>{worker.value?.terminate();});constcall=async<TIn,TOut>(fn: string,payload?: TIn): Promise<TOut>=>{if(!worker.value)thrownewError('Worker not initialized');returnworker.value.call<TIn,TOut>(fn,payload);};return{ worker, loading, error, call };}

🏗️ Building WASM Modules

Quick Example

#[no_mangle]pubextern"C"fnadd(a:i32,b:i32) -> i32{
a + b
}#[no_mangle]pubextern"C"fnfib(n:u32) -> u64{if n <= 1{return n asu64;}fib(n - 1) + fib(n - 2)}

Build:

cargo build --target wasm32-unknown-unknown --release

Running the Example

# 1. Build the WASM modulecd examples/rust-add
./build.sh
# 2. Run the demo (from repo root)cd ../..
pnpm demo

The demo app will open at http://localhost:3000 with the example pre-loaded!

Complete Guide

For detailed instructions on building WASM modules, optimization tips, and creating your own examples, see:

📚 Examples Guide - Complete guide with step-by-step instructions

Available examples:

  • rust-add - Basic Rust WASM module with arithmetic and Fibonacci

🎯 Architecture

┌─────────────────┐ ┌──────────────────┐
│ Main Thread │ │ WebWorker │
│ │ │ │
│ WasmWorker SDK │ ◄─────► │ WASM Runtime │
│ │ Messages │ │
│ Your App Code │ │ WASM Module │
└─────────────────┘ └──────────────────┘

WasmWorker uses a structured message protocol for communication:

  • init: Initialize worker with WASM module
  • call: Execute a WASM function
  • result: Successful result
  • error: Error with code and details

🔧 Development

Setup

# Install dependencies
pnpm install
# Build all packages
pnpm build
# Build WASM examplecd examples/rust-add && ./build.sh
# Run demo
pnpm demo

Project Structure

wasmworker/
├── packages/
│ └── sdk/ # Main SDK package
│ ├── src/
│ │ ├── index.ts # Public API
│ │ ├── bridge.ts # WasmWorker class
│ │ ├── types.ts # TypeScript types
│ │ └── worker/
│ │ └── runtime.ts # Worker script
│ └── tests/ # Unit tests
├── apps/
│ └── demo/ # Demo application
├── examples/
│ └── rust-add/ # Rust WASM example
└── README.md

Scripts

  • pnpm build - Build all packages
  • pnpm dev - Start demo in dev mode
  • pnpm demo - Run demo application
  • pnpm test - Run all tests
  • pnpm typecheck - Type check all packages

🚦 Error Codes

CodeDescription
MODULE_FETCH_FAILEDFailed to fetch WASM module
WASM_INIT_FAILEDFailed to initialize WASM module
FN_NOT_FOUNDFunction not found in WASM exports
INVALID_PAYLOADInvalid payload type
WASM_TRAPWASM execution error/trap
NOT_INITIALIZEDWorker not initialized

🗺️ Roadmap

Core Features

  • Persistent Worker Sessions - Keep worker + WASM instance alive across calls with retained memory/state. Critical for model caching and incremental AI inference.
  • Worker Pooling - Automatically spawn and manage multiple workers. Enables parallel inference or batching for multiple requests.
  • Streaming Results - Return data incrementally via async iterators. Essential for token-by-token AI model outputs.
  • Type-Safe Bindings - Auto-generate TypeScript interfaces from WASM exports. Improves DX with full type safety.
  • WASI Support - Extended compatibility with WASI-enabled runtimes. Helpful for advanced AI libraries.
  • Memory Management Helpers - Tools for efficient memory allocation/deallocation patterns.

Upcoming Examples

  • 🤖 Mini AI Inference Worker - Lightweight model (sentiment classifier, keyword extractor) running entirely in browser with persistent WASM worker keeping model in memory
  • 📊 Real-time Analytics Engine - Process streaming data with WebAssembly
  • 🎨 Image Processing Pipeline - Parallel image transformation using worker pool
  • 🔐 Cryptography Suite - Secure operations in isolated workers

Future Enhancements

  • Multiple module support with dependency resolution
  • Advanced error recovery and retry mechanisms
  • Performance profiling and monitoring tools
  • Browser compatibility testing suite
  • WebGPU integration for hybrid compute

🌐 Browser Support

  • Chrome/Edge: 79+
  • Firefox: 79+
  • Safari: 15.4+

Requires:

  • WebAssembly support
  • WebWorker support
  • ES2022 features

📄 License

MIT © 2025 — Created by Baris Guler

About

⚡ Supercharge your browser with native-speed workers.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages