Web Workers

The following examples demonstrate the basic usage of Worker1 in Univer.

In Sheets, Workers are commonly used for compute-intensive tasks such as formula calculation. Running formula calculation in a Worker process can reduce pressure on the main thread and keep page rendering and interactions responsive when a workbook contains many formulas.

Plugin Mode

Start from the Plugin Mode setup in installation. Keep the rendering and UI plugins on the main thread. Replace the existing registrations of the three calculation plugins below, then add the main-thread RPC plugin before creating the workbook.

TypeScript
import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula'import { UniverRPCMainThreadPlugin } from '@univerjs/rpc'import { UniverSheetsPlugin } from '@univerjs/sheets'import { UniverSheetsFormulaPlugin } from '@univerjs/sheets-formula'univer.registerPlugin(UniverRPCMainThreadPlugin, {  workerURL: new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' }),})univer.registerPlugin(UniverFormulaEnginePlugin, { notExecuteFormula: true })univer.registerPlugin(UniverSheetsPlugin, { notExecuteFormula: true })univer.registerPlugin(UniverSheetsFormulaPlugin, { notExecuteFormula: true })

The Worker contains only the data and calculation plugins shown below; do not register UI or rendering plugins there. notExecuteFormula: true delegates main-thread calculation to the Worker.

TypeScript
import { LocaleType, Univer } from '@univerjs/core'import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula/worker'import { UniverRPCWorkerThreadPlugin } from '@univerjs/rpc/worker'import { UniverSheetsPlugin } from '@univerjs/sheets/worker'import { UniverRemoteSheetsFormulaPlugin } from '@univerjs/sheets-formula/worker'const univer = new Univer({ locale: LocaleType.EN_US })univer.registerPlugin(UniverSheetsPlugin, { onlyRegisterFormulaRelatedMutations: true })univer.registerPlugin(UniverFormulaEnginePlugin)univer.registerPlugin(UniverRPCWorkerThreadPlugin)univer.registerPlugin(UniverRemoteSheetsFormulaPlugin)

When using filters, register UniverSheetsFilterPlugin in both threads so formulas such as SUBTOTAL see filtered rows: import it from @univerjs/sheets-filter on the main thread and @univerjs/sheets-filter/worker in the Worker. Keep UniverSheetsFilterUIPlugin on the main thread.

Use these entry points for additional calculation plugins in the Worker. The main thread uses each package’s root entry. Keep all SDK package versions aligned.

TypeScript
import { UniverProFormulaEnginePlugin } from '@univerjs-pro/engine-formula/worker'import { UniverSheetsPivotChartWorkerPlugin } from '@univerjs-pro/sheets-pivot-chart/worker'import { UniverSheetsPivotTablePlugin } from '@univerjs-pro/sheets-pivot/worker'import { UniverSheetsSlicerPlugin } from '@univerjs-pro/sheets-slicer/worker'import { UniverSheetsTablePlugin } from '@univerjs/sheets-table/worker'

For pivot tables, replace UniverFormulaEnginePlugin with UniverProFormulaEnginePlugin in both threads, and also register UniverLicensePlugin and UniverSheetsPivotTablePlugin. Set notExecuteFormula: true on the Pro formula engine and PivotTable plugin in the main thread, and false in the Worker. Supply the license in both runtimes, keep the pivot UI on the main thread, and register custom formula implementations in both formula engines.

Preset Mode

workerURL option in UniverSheetsCorePreset configuration allows you to specify the URL of the Worker and enable Worker mode.

Example: sheets-core-with-worker

This example imports the sheets-filter preset package because the SUBTOTAL formula calculation is affected by hidden rows in sheets-filter. When formula calculations are executed in a Worker, sheets-filter also needs to be executed in the Worker.

TypeScript
import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US'import { UniverSheetsFilterPreset } from '@univerjs/preset-sheets-filter'import UniverPresetSheetsFilterEnUS from '@univerjs/preset-sheets-filter/locales/en-US'import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'import '@univerjs/preset-sheets-core/lib/index.css'import '@univerjs/preset-sheets-filter/lib/index.css'const { univerAPI } = createUniver({  locale: LocaleType.EN_US,  locales: {    [LocaleType.EN_US]: mergeLocales(      UniverPresetSheetsCoreEnUS,      UniverPresetSheetsFilterEnUS,    ),  },  presets: [    UniverSheetsCorePreset({      workerURL: new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' }),    }),    UniverSheetsFilterPreset(),  ],})univerAPI.createWorkbook({ name: 'Test Sheet' })
TypeScript
import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US'import { UniverSheetsCoreWorkerPreset } from '@univerjs/preset-sheets-core/worker'import UniverPresetSheetsFilterEnUS from '@univerjs/preset-sheets-filter/locales/en-US'import { UniverSheetsFilterWorkerPreset } from '@univerjs/preset-sheets-filter/worker'import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'createUniver({  locale: LocaleType.EN_US,  locales: {    [LocaleType.EN_US]: mergeLocales(      UniverPresetSheetsCoreEnUS,      UniverPresetSheetsFilterEnUS,    ),  },  presets: [    UniverSheetsCoreWorkerPreset(),    UniverSheetsFilterWorkerPreset(),  ],})

Example: sheets-collaboration-with-worker

TypeScript
import { UniverSheetsAdvancedPreset } from '@univerjs/preset-sheets-advanced'import UniverPresetSheetsAdvancedEnUS from '@univerjs/preset-sheets-advanced/locales/en-US'import { UniverSheetsCollaborationPreset } from '@univerjs/preset-sheets-collaboration'import UniverPresetSheetsCollaborationEnUS from '@univerjs/preset-sheets-collaboration/locales/en-US'import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US'import { UniverSheetsDrawingPreset } from '@univerjs/preset-sheets-drawing'import UniverPresetSheetsDrawingEnUS from '@univerjs/preset-sheets-drawing/locales/en-US'import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'import '@univerjs/preset-sheets-core/lib/index.css'import '@univerjs/preset-sheets-drawing/lib/index.css'import '@univerjs/preset-sheets-advanced/lib/index.css'import '@univerjs/preset-sheets-collaboration/lib/index.css'const { univerAPI } = createUniver({  locale: LocaleType.EN_US,  locales: {    [LocaleType.EN_US]: mergeLocales(      UniverPresetSheetsCoreEnUS,      UniverPresetSheetsDrawingEnUS,      UniverPresetSheetsAdvancedEnUS,      UniverPresetSheetsCollaborationEnUS,    ),  },  collaboration: true,  presets: [    UniverSheetsCorePreset({      workerURL: new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' }),    }),    UniverSheetsDrawingPreset({      collaboration: true,    }),    UniverSheetsAdvancedPreset({      useWorker: true,      license: process.env.UNIVER_CLIENT_LICENSE || 'your license.txt',    }),    UniverSheetsCollaborationPreset({    }),  ],})
TypeScript
import UniverPresetSheetsAdvancedEnUS from '@univerjs/preset-sheets-advanced/locales/en-US'import { UniverSheetsAdvancedWorkerPreset } from '@univerjs/preset-sheets-advanced/worker'import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US'import { UniverSheetsCoreWorkerPreset } from '@univerjs/preset-sheets-core/worker'import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'createUniver({  locale: LocaleType.EN_US,  locales: {    [LocaleType.EN_US]: mergeLocales(      UniverPresetSheetsCoreEnUS,      UniverPresetSheetsAdvancedEnUS,    ),  },  presets: [    UniverSheetsCoreWorkerPreset(),    UniverSheetsAdvancedWorkerPreset({      license: process.env.UNIVER_CLIENT_LICENSE || 'your license.txt',    }),  ],})

Footnotes

  1. A Web Worker runs JavaScript outside the browser’s main thread and exchanges messages with it. It cannot access the page DOM directly; moving calculations into a Worker does not move the editor UI there. ↩

How is this guide?

© 2026 DreamNum Co., Ltd.