Web Workers

The following examples demonstrate the basic usage of Worker 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.

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',    }),  ],})

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'import { UniverRPCWorkerThreadPlugin } from '@univerjs/rpc'import { UniverSheetsPlugin } from '@univerjs/sheets'import { UniverRemoteSheetsFormulaPlugin } from '@univerjs/sheets-formula'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 from @univerjs/sheets-filter in both threads so formulas such as SUBTOTAL see filtered rows. Keep UniverSheetsFilterUIPlugin on the main thread.

For pivot tables, also register UniverLicensePlugin, UniverProFormulaEnginePlugin, and UniverSheetsPivotTablePlugin in both threads. Set notExecuteFormula: true on the latter two 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.

How is this guide?

© 2026 DreamNum Co., Ltd.