Worker
CPU-bound JavaScript on up to 8 OS threads. Each Worker has its own JS runtime, event loop, and heap (32 MB) — no shared state, only messages.
Constructor
Throws TypeError: Worker requires a module path with no argument.
options.data that cannot be cloned throws value could not be cloned.
The parameter is named "module path", but the file is evaluated as a classic script (
EVAL_TYPE_GLOBAL) —import/exportinside a worker file is aSyntaxError. Wrap shared code by copying it, or load it in the main thread.
Parent side
Methods
Handlers
Both are single-valued properties — assigning twice replaces the first.
Worker side
Globals available inside the worker file:
Not available: fetch, fs, http, Database, sql, process,
import.
Message contract
Values are structured-cloned across the boundary:
Cloning copies: the receiver gets a snapshot, not a reference. Mutations
after postMessage do not propagate.
Limits
Pattern: worker pool
Eight is the ceiling — beyond that, queue in JS and keep 8 warm.
Lifecycle
- A worker never exits on its own — even an empty script keeps its
thread alive, so the main process waits. Call
terminate(). terminate()is immediate; pendingpostMessages in flight are lost.- An uncaught throw in the worker fires
onerroron the parent; the worker thread keeps running unless you terminate it.
Gotchas
- Worker files are classic scripts — no
import/export, no top-levelawait. - No shared memory:
SharedArrayBufferexists as a global but Workers don't share one — messages are the contract. structuredCloneis not a global; message passing is your clone.- 4 MB messages are expensive — send indices, not payloads.
consolein a worker writes to the same stderr — prefix it (console.log("[w" + workerData.id + "]")).
See also
- Workers guide
- Concurrency — when a Worker is the wrong tool
- Event loop — main-thread liveness
- Limitations
