Usage with function
createWorker lets you spin up an inline Web Worker from a single function.
It is the quickest way to offload CPU-heavy or blocking logic without creating a separate worker file.
Use this API when you don’t need imports or captured variables.
TypeScript example
import { createWorker } from 'lite-worker';
// Must be self-contained (no external imports or captured variables)
const add = (a: number, b: number) => a + b;
const worker = createWorker(add);
const result = await worker.execute(1, 2);
console.log(result); // 3
worker.terminate(); // cleanup when you're done
JavaScript example
import { createWorker } from 'lite-worker';
const normalizeData = async (data) => {
// simulate async work
await new Promise((resolve) => setTimeout(resolve, 1000));
const max = Math.max(...data);
return data.map((score) => Number((score / max).toFixed(2)));
};
const worker = createWorker(normalizeData);
const result = await worker.execute([50, 80, 100]);
console.log(result); // [0.5, 0.8, 1]
worker.terminate();
Handling errors
If your worker throw an error or a rejects promise, it will bubbles back to the main thread.
import { createWorker } from 'lite-worker';
const fetchData = async () => {
const response = await fetch('https://invalidurl...'); // wrong url
const result = await response.json();
return result;
};
const worker = createWorker(fetchData);
try {
const result = await worker.execute();
console.log(result);
} catch (e) {
console.log(e); // TypeError: Failed to fetch
}
Multiple calls
When you use Web Workers directly(worker.postMessage...) sometimes responses can come back out of order if asynchronous work finishes at different times.
lite-worker keeps each request paired with its result, so you can make concurrent calls and safely await them.
import { createWorker } from 'lite-worker';
const heavyTask = async (input: number) => {
await new Promise((resolve) => setTimeout(resolve, 500));
return input * input;
};
const worker = createWorker(heavyTask);
const result1 = worker.execute(10);
const result2 = worker.execute(20);
const result3 = worker.execute(30);
const allResults = await Promise.all([result1, result2, result3]);
console.log(allResults); //[100, 400, 900]
One worker, many functions
Web Workers can only receive data and return data, you can’t export functions from the worker and call them on the main thread. If you’d rather keep everything in one worker instead of creating many workers, wrap the logic in a single entry point and choose the right helper based on the payload.
createWorker accepts one function, but that function can create any number of helpers and decide which one to run at execution time. Keep those helpers inside the worker, send in plain data, and work with the results that come back.
import { createWorker } from 'lite-worker';
type Operation = 'add' | 'multiply' | 'divide';
const worker = createWorker((payload: { op: Operation; a: number; b: number }) => {
const toolsSet = () => {
const add = (a: number, b: number) => a + b;
const multiply = (a: number, b: number) => a * b;
const divide = (a: number, b: number) => a / b;
return { add, multiply, divide };
};
const helpers = toolsSet();
const fn = helpers[payload.op];
return fn(payload.a, payload.b);
});
const sum = await worker.execute({ op: 'add', a: 7, b: 7 });
console.log(sum); // 14
const divide = await worker.execute({ op: 'divide', a: 20, b: 2 });
console.log(divide); // 10
Tips
- Pass in data via arguments, avoid relying on outer scope variables.
- Throw clear errors in your worker functions so the main thread receives helpful messages.
- Always call
terminate()when the worker is no longer needed to free resources. - Web Workers accept arguments that can be structured-cloned, so stick to plain objects, arrays, numbers, strings, and other serializable data.
- For code that requires imports or shared utilities, switch to
createWorkerFromFile.