Skip to content

feat: add "use worker" directive for server Worker Threads and client Web Workers#312

Open
lazarv wants to merge 2 commits intomainfrom
feat/workers
Open

feat: add "use worker" directive for server Worker Threads and client Web Workers#312
lazarv wants to merge 2 commits intomainfrom
feat/workers

Conversation

@lazarv
Copy link
Owner

@lazarv lazarv commented Feb 24, 2026

Summary

This PR introduces the "use worker" directive — a new framework-level primitive that lets developers offload computation to Node.js Worker Threads on the server and Web Workers in the browser using a single, unified API.

Features

"use worker" directive

  • Add a "use worker" directive at the top of any module to mark all its exports as worker functions.
  • At build time, the framework replaces exports with thin proxy stubs; the original code is moved into a virtual module that runs inside the worker thread.
  • Works transparently on both server and client — the framework picks node:worker_threads or the browser Worker API automatically.

RSC Flight protocol serialization

  • All arguments and return values are serialized via the React Server Components Flight protocol.
  • Worker functions can return plain values, React elements, Suspense boundaries, Promises (for deferred rendering with use()), and ReadableStreams.
  • ReadableStream values are transferred (zero-copy) between threads via postMessage transfer lists.

Server-side Worker Threads

  • Workers are spawned lazily on first call and reused across requests.
  • Automatic restart on crash.
  • Worker context (AsyncLocalStorage) provides access to an abort signal for cancellation.
  • Full integration with the framework's logging and dev server (Vite module runner support).

Client-side Web Workers

  • Same "use worker" directive works in client components.
  • The framework generates a Web Worker entry that imports the virtual module and wires up the message protocol.
  • Transparent promise-based API — call worker functions as regular async functions.

after() API

  • New after() server API (exported from @lazarv/react-server) that schedules callbacks to run after the response has been sent to the client.
  • Useful for logging, analytics, cleanup, or fire-and-forget tasks.

Build & Dev integration

  • New Vite plugin (react-server:use-worker) handles module transformation, virtual module resolution, and worker entry generation for both dev and production builds.
  • Dev mode uses Vite's ModuleRunner inside workers for HMR-compatible execution.
  • Production build emits worker chunks alongside the main server/client bundles.

Flight streaming improvements

  • Enhanced toStream / fromStream helpers in @lazarv/react-server/rsc (and rsc/browser) to support streaming serialization of complex React trees, Promises, and ReadableStreams across thread boundaries.
  • Comprehensive test suite (flight-streaming.test.mjs) covering primitives, nested objects, React elements, Suspense, error propagation, streams, and concurrent calls.

New files

Path Description
packages/react-server/lib/plugins/use-worker.mjs Vite plugin for "use worker" directive
packages/react-server/server/worker-proxy.mjs Server-side worker thread manager
packages/react-server/server/worker-proxy-edge.mjs Edge-compatible worker proxy stub
packages/react-server/server/worker-context.mjs AsyncLocalStorage context for workers
packages/react-server/client/worker-proxy.mjs Client-side Web Worker proxy
packages/react-server/server/after.mjs after() API implementation
packages/react-server/lib/dev/worker.mjs Dev-mode worker thread entry
packages/react-server/lib/start/worker.mjs Production worker thread entry
docs/src/pages/en/(pages)/framework/worker.mdx Documentation page
examples/use-worker/ Full example app demonstrating server & client workers
test/__test__/apps/use-worker.spec.mjs Integration tests
packages/rsc/__tests__/flight-streaming.test.mjs Flight protocol streaming tests

Modified files

  • packages/rsc/client/shared.mjs / packages/rsc/server/shared.mjs — Enhanced Flight streaming helpers (toStream, fromStream) for cross-thread serialization.
  • packages/react-server/server/index.mjs / index.d.ts — Export new after() and logger APIs.
  • packages/react-server/server/symbols.mjs — New runtime symbols for worker context.
  • packages/react-server/server/runtime.mjs — Runtime support for after() callbacks.
  • packages/react-server/server/render-rsc.jsx / request.mjs — Wire up after() execution post-response.
  • packages/react-server/lib/build/server.mjs / client.mjs — Include worker plugin in build pipeline.
  • packages/react-server/lib/dev/create-server.mjs — Dev server worker thread setup.
  • packages/react-server/lib/start/create-server.mjs — Production server worker setup.
  • packages/react-server/lib/http/middleware.mjsafter() callback execution in HTTP middleware.
  • packages/react-server/client/ClientProvider.jsx / error-overlay.mjs — Client-side worker integration.
  • docs/ — Updated framework docs index and added worker documentation page.

@codecov-commenter
Copy link

codecov-commenter commented Feb 24, 2026

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
1361 1 1360 4
View the top 1 failed test(s) by shortest run time
__test__/apps/use-worker.spec.mjs > use worker > terminate worker and page recovers
Stack Traces | 33.8s run time
Error: page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:4459/
Call log:
  - navigating to "http://localhost:4459/", waiting until "load"

 ❯ __test__/apps/use-worker.spec.mjs:79:16

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants