> For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt.

# Web Workers

This guide explains how to configure and use [Web Workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers) in Rslib projects.

:::note

When using Web Workers, only ESM output can be generated, so [format](/config/lib/format.md) must be set to `'esm'` (default).

:::

## Use the worker constructor

### Basic usage

You can create a Worker with the standard constructor syntax:

```ts title="index.ts"
new Worker(new URL('./worker.ts', import.meta.url));
```

Rslib rewrites the Worker URL to reference the generated JavaScript file and emits the Worker as an ES module:

```js title="index.js"
new Worker(new URL('./worker.js', import.meta.url), {
  type: 'module',
});
```

More Worker syntax can be found in [Rspack - Web Workers](https://rspack.rs/guide/features/web-workers).

### Limitations

Rslib relies on static analysis to process `new Worker` and similar Worker APIs, so you must pass `new URL('./worker.ts', import.meta.url)` directly. URL strings and URL objects passed through variables are not supported:

```ts
new Worker('./worker.ts');

const workerUrl = new URL('./worker.ts', import.meta.url);
new Worker(workerUrl);
```

### Output modes

The [lib.bundle](/config/lib/bundle.md) option determines how Workers are built. The following example uses the same source files to show the output generated in bundle and bundleless modes:


**src/index.ts**

```ts
export const worker = new Worker(new URL('./worker.ts', import.meta.url));
```


**src/worker.ts**

```ts
import { add } from './helper';

self.onmessage = ({ data }: MessageEvent<[number, number]>) => {
  self.postMessage(add(data[0], data[1]));
};
```


**src/helper.ts**

```ts
export const add = (left: number, right: number) => left + right;
```


#### Bundle mode

In bundle mode, Rslib emits the Worker entry as a separate chunk and bundles modules imported by the Worker into that chunk:


**dist/index.js**

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


**dist/worker.js**

```js
const add = (left, right) => left + right;
self.onmessage = ({ data }) => {
  self.postMessage(add(data[0], data[1]));
};
export {};
```


#### Bundleless mode

In bundleless mode, Rslib preserves the source module structure and rewrites Worker URLs and imports inside Workers to reference the corresponding ESM output files:


**dist/index.js**

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


**dist/worker.js**

```js
import { add } from './helper.js';
self.onmessage = ({ data }) => {
  self.postMessage(add(data[0], data[1]));
};
```


**dist/helper.js**

```js
const add = (left, right) => left + right;
export { add };
```


## Import with query suffixes

Rslib supports importing Web Workers with query suffixes in bundle mode; for details, see [Rsbuild - Web Workers](https://rsbuild.rs/guide/basic/web-workers#import-with-query-suffixes).

### Emit a separate worker file

You can append `?worker` to an import request to import a Web Worker script, which Rslib emits as a separate ESM file:

```ts title="index.ts"
import MyWorker from './worker.ts?worker';

export const worker = new MyWorker();
```

### Inline a worker

You can append `?worker&inline` to an import request to import a Web Worker script, which Rslib inlines into the JavaScript file that imports the Worker instead of emitting a separate Worker file:

```ts title="index.ts"
import InlineWorker from './worker.ts?worker&inline';

export const worker = new InlineWorker();
```

### Type declarations

When you import a Worker with a query suffix in TypeScript code, TypeScript may report that the module is missing type definitions:

```
TS2307: Cannot find module './worker.ts?worker' or its corresponding type declarations.
```

In this case, you can add the [preset types](/guide/basic/typescript.md#preset-types) provided by `@rslib/core` to `tsconfig.json`:

```json title="tsconfig.json"
{
  "compilerOptions": {
    "types": ["@rslib/core/types"]
  }
}
```

The preset types include declarations for `*?worker`, `*?worker&inline`, and `*?inline&worker`.
