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.
How it runs
Section titled “How it runs”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.