October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk5 min

React Web Workers with Comlink: Practical Patterns

Use Comlink to call a worker’s exposed API asynchronously from React, while keeping DOM work on the main thread and worker setup and cleanup aligned with the component lifecycle.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To use Comlink with a React Web Worker, create a worker, expose a small API from its script, wrap the worker with Comlink.wrap(), and call its methods with await. Keep React rendering and DOM work on the main thread; use the worker for computation that is expensive enough to justify sending data across a separate execution context. Tie a component-owned worker to an Effect’s setup and cleanup so it is released on unmount and when its dependencies change.

What happens when React calls a worker through Comlink?

A Web Worker runs in a separate execution context. It can perform computation without occupying the main thread, but it cannot manipulate the page DOM or directly update React state. The main thread and worker communicate by messages: ordinary workers use postMessage() and message events, with data structured-cloned by default unless supported transferable values are explicitly transferred. MDN’s Web Workers guide describes the execution boundary and message model.

As an Amazon Associate I earn from qualifying purchases.

Comlink wraps the worker endpoint in a proxy so the main thread can call exposed worker methods without writing each message handler by hand. The boundary does not disappear: remote property access and method calls are asynchronous, and values still have to follow structured-clone, transfer, or proxy rules. The Comlink project describes its goal as “Comlink makes WebWorkers enjoyable.” Comlink README

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Define a small worker API

Put computation in a worker module and expose only the operations the React feature needs. Keep DOM access, rendering, and state updates in React. This separation makes it clear which inputs cross the boundary and which results return to the component.

// calculation.worker.js
import * as Comlink from 'comlink';

const api = {
  async calculate(input) {
    // Perform worker-compatible computation here.
    return expensiveCalculation(input);
  },
};

Comlink.expose(api);

The example assumes expensiveCalculation is implemented in the worker-compatible code available to this module. A worker should not depend on the document or on React state; send the needed input and return a result instead.

Create and dispose of a component-owned worker

For a worker owned by one mounted feature, an Effect can create the worker and Comlink proxy, invoke the API, and clean up both resources. The example uses Vite’s documented module-worker constructor syntax; adapt the path and import style to your bundler and its version.

import { useEffect, useState } from 'react';
import * as Comlink from 'comlink';

export function Calculator({ input }) {
  const [result, setResult] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    const worker = new Worker(
      new URL('./calculation.worker.js', import.meta.url),
      { type: 'module' },
    );
    const api = Comlink.wrap(worker);
    let active = true;

    async function run() {
      try {
        const value = await api.calculate(input);
        if (active) {
          setResult(value);
          setError(null);
        }
      } catch (cause) {
        if (active) setError(cause);
      }
    }

    run();
    return () => {
      active = false;
      api[Comlink.releaseProxy]();
      worker.terminate();
    };
  }, [input]);

  if (error) return <p>Calculation failed.</p>;
  return <pre>{JSON.stringify(result)}</pre>;
}

In this pattern, the active flag prevents a completed call from setting state after its Effect has been cleaned up. Releasing the Comlink proxy and terminating a dedicated worker serve different purposes: release the proxy’s resources, then stop the worker that this Effect created. React’s Effect guidance says cleanup runs before setup repeats for changed dependencies and on unmount; in development, Strict Mode adds an extra setup-cleanup cycle to reveal incomplete cleanup. React’s useEffect reference

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keep dependencies intentional

The example recreates its worker whenever input changes. That can be appropriate for infrequent changes, but unstable object or function identities can cause needless Effect restarts. Stabilize inputs where appropriate, or use a persistent worker if calls are frequent. With a persistent worker, consider request identifiers or another ordering strategy so an older result cannot replace a newer one; that coordination is application logic, not automatic Comlink behavior.

Use the worker constructor your bundler supports

MDN recommends constructing workers with a URL relative to import.meta.url for common bundlers. Vite documents this form:

new Worker(new URL('./calculation.worker.js', import.meta.url), {
  type: 'module',
});

Vite also supports importing a worker with the ?worker suffix. Its documentation says worker detection for the constructor form expects the new URL(..., import.meta.url) expression directly inside new Worker(); hiding that expression behind an intermediate variable may prevent the expected build handling. Check the documentation for the Vite version used by the project, since the guide is maintained over time. Vite’s Web Workers guide

Choose how values cross the boundary

Comlink uses structured cloning by default. That is convenient for ordinary serializable data, but it means the worker receives a copy rather than shared access to the original object. For supported transferable objects such as an ArrayBuffer, use Comlink.transfer(value, [transferable]) when transferring ownership is suitable; account for the sender no longer having normal access to the transferred resource.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Functions cannot be structured-cloned or transferred as ordinary values. If the worker needs to call a function supplied by the main thread, wrap it with Comlink.proxy(callback). For custom values, Comlink transfer handlers can define serialization and deserialization on both endpoints. An Event is not directly cloneable, so pass a purpose-built serializable representation of the information the worker needs rather than the event itself. Comlink README

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Handle errors and inspect worker failures

Use ordinary promise error handling around remote calls: Comlink rethrows exceptions from the other side, so a rejected worker call should be caught where the component can decide how to present or recover from it. The example catches failures from calculate(). You can also attach an error event listener to the Worker object for failures surfaced through the Worker API. MDN documents worker error events and terminate(); browser developer tools can inspect worker sources, logs, and breakpoints. MDN’s Web Workers guide

Choose Comlink, raw messages, or a different worker type

Choice Useful when Trade-off
Raw postMessage() You want explicit message types, protocol control, or minimal abstraction. You must implement and maintain message handling yourself; data still follows clone and transfer rules.
Comlink You want a small asynchronous API rather than hand-written message plumbing. Calls remain asynchronous, and the worker boundary and data-transfer rules remain in effect.
Dedicated worker A feature or component should own its worker lifecycle. The creating context owns the worker; component cleanup should release and terminate it.
SharedWorker Multiple same-origin windows or scripts need to connect to shared worker execution. Communication uses a port, and Comlink’s SharedWorker setup wraps that port and exposes the API on connection.

Neither Comlink nor a worker guarantees a speedup for every task. Offloading may improve responsiveness when laborious processing would otherwise block the main execution thread, but messaging and data handling also have costs. There is no established React-plus-Comlink benchmark here that supports a numerical gain or a universal threshold, so measure the workload in the application that will use it. MDN on Web Workers Comlink README

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.