A lightweight, type-safe React hook for seamlessly integrating Web Workers into your React applications. Run expensive computations off the main thread without managing worker files or dealing with complex worker setup.
- π Simple API with a single hook
- π¦ No separate worker files needed
- πͺ Full TypeScript support
- π Automatic worker lifecycle management
- β‘ Support for transferable objects
- βοΈ Optional React Suspense integration
- π Built-in cancellation support
npm install ez-web-worker
import { useWorker } from 'ez-web-worker';
function MyComponent() {
const { run, cancel, result, status, error } = useWorker((input: number) => {
// This code runs in a Web Worker
let total = 0;
for (let i = 0; i < 1e8; i++) {
total += (i * input) % 1234567;
}
return total;
});
return (
<div>
<button onClick={() => run(42)}>Start Calculation</button>
<button onClick={cancel}>Cancel</button>
{status === 'running' && <p>Calculating...</p>}
{status === 'done' && <p>Result: {result}</p>}
{status === 'error' && <p>Error: {error?.message}</p>}
</div>
);
}
You can also use the worker functionality without React using the createWorker
function:
import { createWorker } from 'ez-web-worker';
// Create a worker instance
const worker = createWorker((input: number) => {
// This code runs in a Web Worker
let total = 0;
for (let i = 0; i < 1e8; i++) {
total += (i * input) % 1234567;
}
return total;
});
// Run the worker
worker.run(42)
.then(result => console.log('Result:', result))
.catch(error => console.error('Error:', error));
// Clean up when done
worker.terminate();
import { createWorker } from 'ez-web-worker';
import { useQuery } from '@tanstack/react-query';
const computationWorker = createWorker((input: number) => {
// Your heavy computation here
return input * 2;
});
function MyComponent() {
const { data, isLoading } = useQuery({
queryKey: ['computation', 42],
queryFn: () => computationWorker.run(42)
});
// Don't forget to clean up
useEffect(() => {
return () => computationWorker.terminate();
}, []);
return isLoading ? <div>Loading...</div> : <div>Result: {data}</div>;
}
useWorker<TArgs, TResult>(workerFn: (args: TArgs) => TResult | Promise<TResult>, options?: WorkerOptions): UseWorkerReturn<TArgs, TResult>
workerFn
: The function to run in the Web Worker. Must be self-contained (no closure variables).options
: Optional configuration objectsuspense?: boolean
: Enable React Suspense integrationtransferable?: boolean
: Enable automatic transferable object handling
run: (args: TArgs) => void
: Execute the worker functioncancel: () => void
: Cancel the current executionresult: TResult | null
: The result of the computationstatus: 'idle' | 'running' | 'done' | 'error'
: Current worker statuserror: Error | null
: Error object if the computation failed
function ProcessImageData() {
const { run, result } = useWorker(
(imageData: ArrayBuffer) => {
// Process image data in worker
return processedData;
},
{ transferable: true }
);
const handleImageUpload = (e) => {
const file = e.target.files[0];
const reader = new FileReader();
reader.onload = () => run(reader.result as ArrayBuffer);
reader.readAsArrayBuffer(file);
};
return <input type="file" onChange={handleImageUpload} />;
}
function App() {
return (
<Suspense fallback={<LoadingSpinner />}>
<ExpensiveComponent />
</Suspense>
);
}
function ExpensiveComponent() {
const { run, result } = useWorker(
expensiveFunction,
{ suspense: true }
);
// Component will suspend while worker is running
return <div>{result}</div>;
}
- Worker functions must be self-contained and cannot reference variables from their outer scope
- DOM APIs are not available inside worker functions
- Limited SSR support (workers only run in browser environment)
MIT Β© ethanpv34