Skip to content

Workers

Checked against f15b998 on 2026-11-10. The files it covers are unchanged since.

new Worker(url) works as on the web: a dedicated worker runs its script on a thread of its own, with a DedicatedWorkerGlobalScope, and talks to the page with postMessage. Messages are structured clones, and MessageChannel and BroadcastChannel exist. A worker’s script and its importScripts load through the page’s own loader, so a worker’s script can come from the app’s bundle like the page’s. It must be same-origin or a data: URL.

Shared workers and service workers aren’t implemented. With no service worker there’s no offline cache or push from a worker; a niso app’s files are local anyway.

Each worker gets a DOM of its own (without a document) and an engine of its own on its thread, and runs its own event loop. Nothing in the page’s DOM is shared with it; only messages cross. Workers need a worker host: niso-core’s WorkerHost trait (crates/niso-core/src/worker.rs), whose C forms are a runner that starts the thread itself (niso_dom_set_worker_runner) or a host that starts workers on threads of its own (niso_dom_set_worker_host). The JS binding on QuickJS sets a runner, so a page’s workers run on QuickJS like the page; Node-API sets a host that runs each worker on one of the runtime’s worker threads. Porffor runs no workers: with no worker host, new Worker() throws a NotSupportedError.

While a worker is busy, the page’s event loop runs in real time rather than skipping ahead on virtual time, so tests that use workers take as long as the workers do. Freeing a page ends its workers, waiting up to two seconds.

The C side is Workers.