Skip to content

worker: add support for Web Workers - #64894

Closed
avivkeller wants to merge 6 commits into
nodejs:mainfrom
avivkeller:web-workers
Closed

worker: add support for Web Workers#64894
avivkeller wants to merge 6 commits into
nodejs:mainfrom
avivkeller:web-workers

Conversation

@avivkeller

@avivkeller avivkeller commented Aug 1, 2026

Copy link
Copy Markdown
Member

Closes: #43583

Adds support for the Web Worker API as defined by the HTML Standard:
https://html.spec.whatwg.org/multipage/workers.html

The implementation trys to follow the specification as close as Node.js allows, so note the following differences:

  • SharedWorker is not implemented. Its lifetime and sharing model depend on origins and browsing contexts, concepts that do not exist in Node.js.

  • Worker scripts are loaded synchronously from the local filesystem rather than fetched over the network. As a result:

    • new Worker() and importScripts() accept only file:, data:, and blob: URLs.
    • Any other scheme throws a NotSupportedError.
    • An unreadable script throws a NetworkError (per the spec, this is emitted as an error event).
    • Redirects, nosniff, and HTTP MIME type validation are not applicable. MIME type validation is performed only for data: and blob: URLs.
    • WorkerOptions.credentials is validated for API compatibility but otherwise has no effect, since no network request is made.
  • Node.js has no origin model. Consequently, concepts such as same-origin and cross-origin do not exist, and location.origin is null for file: workers.

  • close() terminates the worker immediately instead of following the specification's "closing flag" algorithm. Code remaining in the current task after close() is therefore not executed.

  • The worker global is the normal Node.js global object with DedicatedWorkerGlobalScope inserted into its prototype chain rather than the inverse (a fresh global created from the interface). Additionally, classic file: workers are executed through the CommonJS/ESM loaders rather than as classic scripts, so top-level declarations do not become global properties. Classic data: and blob: workers continue to execute as classic scripts.

  • ErrorEvents dispatched to Worker instances include message and error, but not filename, lineno, or colno. Unhandled worker errors are also not propagated further. These are a result of the worker_threads implementation that is underneath the web workers implemantion.

  • The following WorkerGlobalScope events are never dispatched:

    • languagechange, online, and offline, since these concepts do not exist in Node.js.
    • rejectionhandled and unhandledrejection, since Node.js exposes equivalent process-level events but does not implement the PromiseRejectionEvent interface or the per-rejection preventDefault() behavior required by the HTML Standard.
  • On the main thread, relative worker script URLs are resolved against the current working directory because there is no document base URL. Within a worker, relative URLs resolve against the worker's own URL, matching the specification.

AI Disclaimer: I used slight AI help to resolve issues that came up during me validating the WPT tests.

TODO before merge:

  • test WPT Report upload against staging.wpt.fyi with @panva

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/loaders
  • @nodejs/startup
  • @nodejs/web-standards

@nodejs-github-bot nodejs-github-bot added lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Aug 1, 2026
@avivkeller

avivkeller commented Aug 1, 2026

Copy link
Copy Markdown
Member Author

I'm not sure if I should break the WPT additions into their own commit / PR for ease of reviewing?

You should be able to collapse the test folder to view the lib impl changes

Finally, I haven't added dedicated tests for this outside of the WPT, which should cover it.

@avivkeller avivkeller added worker Issues and PRs related to Worker support. web-standards Issues and PRs related to Web APIs semver-minor PRs that contain new features and should be released in the next minor version. labels Aug 1, 2026
Comment thread lib/internal/webworker.js
Comment thread test/common/wpt/webworker.js
@avivkeller avivkeller added commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. experimental Issues and PRs related to experimental features. labels Aug 1, 2026
@jasnell

jasnell commented Aug 1, 2026

Copy link
Copy Markdown
Member

The web platform tests in this PR really ought to be separated out into a separate commit to make reviewing this easier. 1300+ files changes with 54k+ lines changed is very difficult to review in a single commit.

Comment thread doc/api/globals.md Outdated
@avivkeller

Copy link
Copy Markdown
Member Author

The web platform tests in this PR really ought to be separated out into a separate commit to make reviewing this easier. 1300+ files changes with 54k+ lines changed is very difficult to review in a single commit.

Broken up! c73f2fe has the actual changes

@codecov

codecov Bot commented Aug 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.63799% with 71 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.13%. Comparing base (91a99c5) to head (1beb0ab).
⚠️ Report is 20 commits behind head on main.

Files with missing lines Patch % Lines
lib/internal/webworker.js 92.70% 71 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #64894      +/-   ##
==========================================
- Coverage   90.32%   90.13%   -0.19%     
==========================================
  Files         751      752       +1     
  Lines      250000   251424    +1424     
  Branches    47231    47247      +16     
==========================================
+ Hits       225816   226628     +812     
- Misses      15566    16162     +596     
- Partials     8618     8634      +16     
Files with missing lines Coverage Δ
lib/internal/blob.js 89.40% <100.00%> (-0.46%) ⬇️
...internal/bootstrap/web/exposed-window-or-worker.js 91.60% <100.00%> (-2.20%) ⬇️
lib/internal/encoding.js 96.66% <100.00%> (+0.04%) ⬆️
lib/internal/event_target.js 98.78% <100.00%> (-0.40%) ⬇️
lib/internal/main/worker_thread.js 94.91% <100.00%> (+0.55%) ⬆️
lib/internal/modules/helpers.js 98.92% <100.00%> (-0.01%) ⬇️
lib/internal/navigator.js 98.78% <100.00%> (+<0.01%) ⬆️
lib/internal/process/pre_execution.js 97.14% <100.00%> (-0.58%) ⬇️
lib/internal/webidl.js 99.12% <100.00%> (-0.34%) ⬇️
lib/internal/worker.js 96.76% <100.00%> (+0.01%) ⬆️
... and 5 more

... and 57 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread test/fixtures/wpt/README.md
@mcollina

mcollina commented Aug 1, 2026

Copy link
Copy Markdown
Member

This is gargantuan. Can you add a review guide and/or split into chunks?

Comment thread test/wpt/status/workers.json Outdated
Comment thread doc/api/globals.md
@panva

panva commented Aug 1, 2026

Copy link
Copy Markdown
Member

I have:

  • added a commit to accomodate multi-global WPT tests in the runner and reporter
  • added a TODO to the description when this stabilizes to test the daily WPT Report upload against staging.wpt.fyi

@avivkeller

Copy link
Copy Markdown
Member Author

This is gargantuan. Can you add a review guide and/or split into chunks?

It's only extremely large due to the added WPT tests. You can make it easier to review by

  1. Not reviewing the WPT test commit (the second commit in the PR), or
  2. Collapsing the test/fixtures folder in the GitHub UI

Comment thread test/parallel/test-worker-spec-differences.js Outdated
@avivkeller
avivkeller requested review from jasnell and mcollina August 1, 2026 16:41
Comment thread lib/internal/webworker.js Outdated
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Aug 13, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Comment thread lib/internal/bootstrap/web/exposed-window-or-worker.js
Comment thread lib/internal/process/pre_execution.js Outdated
Comment thread eslint.config.mjs
panva and others added 5 commits August 14, 2026 10:40
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
Co-authored-by: Aviv Keller <me@aviv.sh>
Signed-off-by: Aviv Keller <me@aviv.sh>
To hopefully get to the bottom of WPT crashes that have no traces.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
Co-authored-by: Aviv Keller <me@aviv.sh>
Signed-off-by: Aviv Keller <me@aviv.sh>
Signed-off-by: Aviv Keller <me@aviv.sh>
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
Co-authored-by: Aviv Keller <me@aviv.sh>
Signed-off-by: Aviv Keller <me@aviv.sh>
Signed-off-by: Aviv Keller <me@aviv.sh>
@panva

panva commented Aug 14, 2026

Copy link
Copy Markdown
Member

rebased and squashed, i made no functional changes

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@panva panva removed the commit-queue-failed An error occurred while landing this pull request using GitHub Actions. label Aug 14, 2026
@avivkeller avivkeller added request-ci Add this label to start a Jenkins CI on a PR. and removed request-ci Add this label to start a Jenkins CI on a PR. labels Aug 15, 2026
avivkeller added a commit that referenced this pull request Aug 15, 2026
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
Co-authored-by: Aviv Keller <me@aviv.sh>
Signed-off-by: Aviv Keller <me@aviv.sh>
PR-URL: #64894
Fixes: #43583
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matthew Aitken <maitken033380023@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
avivkeller added a commit that referenced this pull request Aug 15, 2026
To hopefully get to the bottom of WPT crashes that have no traces.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
Co-authored-by: Aviv Keller <me@aviv.sh>
Signed-off-by: Aviv Keller <me@aviv.sh>
PR-URL: #64894
Fixes: #43583
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matthew Aitken <maitken033380023@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
avivkeller added a commit that referenced this pull request Aug 15, 2026
Signed-off-by: Aviv Keller <me@aviv.sh>
PR-URL: #64894
Fixes: #43583
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matthew Aitken <maitken033380023@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
avivkeller added a commit that referenced this pull request Aug 15, 2026
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
Co-authored-by: Aviv Keller <me@aviv.sh>
Signed-off-by: Aviv Keller <me@aviv.sh>
PR-URL: #64894
Fixes: #43583
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matthew Aitken <maitken033380023@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
avivkeller added a commit that referenced this pull request Aug 15, 2026
Signed-off-by: Aviv Keller <me@aviv.sh>
PR-URL: #64894
Fixes: #43583
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matthew Aitken <maitken033380023@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
@avivkeller

Copy link
Copy Markdown
Member Author

Landed in c7b962c...c73d0b1

@avivkeller avivkeller closed this Aug 15, 2026
@panva

panva commented Aug 16, 2026

Copy link
Copy Markdown
Member

@avivkeller please follow up with a 27.x semver major flag flip. --no-experimental-* to turn off, on by default, still experimental active development.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author ready PRs that have at least one approval, no pending requests for changes, and a CI started. commit-queue-rebase Add this label to allow the Commit Queue to land a PR in several commits. experimental Issues and PRs related to experimental features. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. review wanted PRs that need reviews. semver-minor PRs that contain new features and should be released in the next minor version. web-standards Issues and PRs related to Web APIs worker Issues and PRs related to Worker support.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Web Workers

10 participants