React Web Worker
A React hook for creating and using web workers without blocking the main thread.
Repository Health
Technical Analysis
@shopify/react-web-worker provides a single React hook, useWorker, that lets components spin up and communicate with a web worker created by @shopify/web-worker’s createWorkerFactory. It re-exports web-worker’s entire public API, so installing this one package is enough to both build worker-ready modules with a Babel/webpack pipeline and consume them from React components.
The hook creates the worker lazily on first render via useLazyRef, exposes it as a proxy whose async methods mirror the worker module’s exports, and automatically calls terminate() when the owning component unmounts. Both react-web-worker and its underlying web-worker package are part of Shopify’s Quilt monorepo and are now marked deprecated by their maintainers, who point consumers toward implementing the pattern directly or migrating to newer tooling.
What You Get
- The useWorker hook for creating and calling into a web worker from inside a React component
- Automatic worker lifecycle management — termination fires on unmount via a useEffect cleanup
- A full re-export of @shopify/web-worker’s API (createWorkerFactory, terminate, Babel/webpack build tooling) from a single import
- TypeScript types for worker return values, including a NoInfer helper so factory arguments type-check correctly
Common Use Cases
- Offloading CPU-heavy work (parsing, image processing, data crunching) off the main thread in a React app
- Keeping a React UI responsive while a worker handles slow synchronous computation
- Wiring a createWorkerFactory-created worker into a component without hand-writing useRef/useEffect cleanup boilerplate
- Migrating existing @shopify/web-worker call sites into React components that need the same background computation
Under The Hood
Architecture The package is a thin, 23-line React wrapper around @shopify/web-worker: hooks.ts defines a single useWorker hook that lazily instantiates a worker via useLazyRef (from @shopify/react-hooks) on first render, exposes the returned proxy directly to the component, and terminates it inside a useEffect cleanup by calling terminate() from the sibling package. index.ts re-exports the entirety of @shopify/web-worker’s public surface, so the real architecture — the message-passing messenger/ layer that proxies calls to worker-exported functions over postMessage, the create/ module that turns a dynamic import() into a worker instance, and the Babel (babel-plugin.ts) and webpack (webpack-parts/) build-time transforms that extract worker code into its own chunk — lives in that dependency, not in this package. Changing the core worker-creation abstraction would require changes in @shopify/web-worker; react-web-worker only needs to track its lifecycle API surface (terminate, the factory’s call signature).
Tech Stack Written in TypeScript and built with Rollup (rollup.config.mjs) into CJS, ESM, and “esnext” outputs matching the package’s conditional exports map, then type-checked across the monorepo with tsc —build. Its only runtime dependencies are sibling Quilt packages — @shopify/react-hooks for useLazyRef, @shopify/useful-types for the NoInfer generic helper, and @shopify/web-worker for worker creation, termination, and build tooling; React and ReactDOM are peer dependencies pinned to the 18.x range. The monorepo as a whole is a Yarn workspaces project versioned with Changesets, linted with ESLint and Prettier, and built/tested via a GitHub Actions Node-CI workflow running Jest.
Code Quality Test coverage for this package is a single file, tests/hooks.test.tsx, with two Jest tests run through @shopify/react-testing’s mount(): one verifies the worker factory is invoked and its result exposed to the component, the other verifies terminate() fires on unmount (with @shopify/web-worker mocked via jest.mock). That’s a narrow but precisely-targeted test surface for a small hook — both of its behaviors (creation, cleanup) are exercised, though there’s no coverage of behavior across re-renders or changing arguments. Types are strict throughout, naming is minimal and consistent with the rest of the monorepo, and the same repo-wide ESLint/Prettier/type-check gates apply via CI.
API Design The useWorker hook itself is intentionally unambitious — a useLazyRef plus a cleanup effect, not a novel pattern in the React ecosystem. Its value is convenience: it saves consumers from hand-wiring the same useRef/useEffect boilerplate around @shopify/web-worker’s lower-level createWorkerFactory/terminate API, which is where the more genuinely novel engineering lives (compile-time extraction of worker modules via a Babel/webpack pipeline, typed RPC over postMessage). Both packages are now explicitly marked deprecated by Shopify, which directs internal consumers toward newer internal tooling and external consumers toward implementing the pattern themselves or choosing a maintained alternative.