univer-plugin-dev
Univer Plugin Development
Guide for building custom plugins that extend Univer's functionality.
Compatibility: This skill is written for Univer
v0.21.x. Core plugin patterns (lifecycle, DI, commands) remain stable, but specific service tokens and facade classes may shift. Prefer the user's existing codebase patterns when they differ from examples here.
Quick Start
Scaffold a new plugin
Use the bundled script to generate a minimal plugin skeleton:
# If installed to ~/.codex/skills/
npx tsx ~/.codex/skills/univer-plugin-dev/scripts/scaffold-plugin.ts my-plugin --path ./src/plugins
# Or from this repo directly
npx tsx ~/univer-sdk-skills/skills/univer-plugin-dev/scripts/scaffold-plugin.ts my-plugin --path ./src/plugins
This creates:
my-plugin/
├── src/
│ ├── index.ts
│ ├── plugin.ts
│ ├── commands/
│ │ └── commands.my-command.ts
│ ├── controllers/
│ │ └── my-menu.controller.ts
│ └── facade/
│ └── f-univer.ts
├── package.json
└── tsconfig.json
Register the plugin in your app
import { MyPlugin } from './plugins/my-plugin/src';
import './plugins/my-plugin/src/facade/f-univer'; // side-effect import for Facade extension
univer.registerPlugin(MyPlugin);
Core Concepts
Plugin Lifecycle
Plugins inherit from Plugin and override lifecycle hooks:
| Hook | When | What to do |
|---|---|---|
onStarting() |
Plugin mounted, no unit yet | Register commands, services, menus, shortcuts |
onReady() |
Business unit created | Access workbook/doc instance |
onRendered() |
UI rendered | DOM-dependent initialization |
onSteady() |
Everything stable | Background tasks |
Always use disposeWithMe() to register disposable resources so they auto-cleanup when the plugin is destroyed.
Command System
Three command types:
- COMMAND — Business entry point. Orchestrates mutations and operations. Supports undo/redo if you manually push to
IUndoRedoService. - MUTATION — Atomic data change. Persisted to snapshot. Automatically undoable.
- OPERATION — UI state change. Not persisted. Not undoable.
See references/command-system.md for full examples of each type and undo/redo construction.
Dependency Injection
Univer uses a custom DI container (Injector). Services are retrieved by:
// Constructor injection
@Inject(IMenuManagerService) private readonly _menuService: IMenuManagerService
// Accessor injection (in command handlers)
const service = accessor.get(IMenuManagerService);
Common service tokens:
ICommandService— register/execute commandsIMenuManagerService— add menus/toolbar itemsIShortcutService— register keyboard shortcutsIContextMenuService— context menusComponentManager— register React components/iconsIUniverInstanceService— get current workbook/doc/slideIUndoRedoService— push undo/redo entries
Facade Extension
Extend Facade classes to expose plugin capabilities to end users:
import { FWorksheet } from '@univerjs/sheets/facade';
class FWorksheetMyMixin extends FWorksheet {
myMethod(): this {
// implementation
return this;
}
}
FWorksheet.extend(FWorksheetMyMixin);
declare module '@univerjs/sheets/facade' {
interface FWorksheet extends FWorksheetMyMixin {}
}
Common Tasks
For full examples (submenus, context menus, Range Popup, component replacement, complete toolbar+command+shortcut pipeline), see references/ui-customization.md.
Add a Toolbar Button
this._menuManagerService.mergeMenu({
[RibbonOthersGroup.OTHERS]: {
['my-button']: {
order: 10,
menuItemFactory: () => ({
id: 'my-button',
title: 'My Button',
type: MenuItemType.BUTTON,
}),
},
},
});
Register a Command
const MyCommand: ICommand = {
id: 'my.command.id',
type: CommandType.COMMAND,
handler: (accessor) => {
// business logic
return true;
},
};
this._commandService.registerCommand(MyCommand);
Extend Facade
class FWorksheetMyMixin extends FWorksheet {
myMethod(): this { return this; }
}
FWorksheet.extend(FWorksheetMyMixin);
declare module '@univerjs/sheets/facade' {
interface FWorksheet extends FWorksheetMyMixin {}
}
References
- Plugin architecture:
references/plugin-architecture.md— lifecycle, DI, service registration, controller pattern - Command system:
references/command-system.md— COMMAND / MUTATION / OPERATION, undo/redo, mutation factories, custom mutations - Facade extension:
references/facade-extension.md— extend FUniver, FWorkbook, FWorksheet, FRange, multiple extensions merge strategy - UI customization:
references/ui-customization.md— menus, submenus, shortcuts, context menus, popups, component replacement - Event system:
references/event-system.md— events, hooks, custom events, RxJS streams
Also see univer-integrate skill for:
- Custom formula functions (
univer-integrateskill) - Permissions (
univer-integrateskill) - Network layer (
univer-integrateskill)
Scripts
- Scaffold:
scripts/scaffold-plugin.ts— generate a new plugin skeleton
More from dream-num/univer-sdk-skills
univer-node-backend
Use Univer (spreadsheet engine) in Node.js backend environments for headless data processing, batch report generation, server-side formula calculation, and automated workbook manipulation. Use when the user needs to create, read, or modify spreadsheets on the server without a browser, run Univer in Node.js, use createUniverOnNode, UniverRPCNodeMainPlugin, child_process fork for formula workers, server-side XLSX/JSON processing, or batch cell operations via Facade API in a backend context. Triggers include "Node.js", "server side", "backend", "headless", "batch generate", "automated report", "createUniverOnNode", "rpc-node", "formula worker", or "Univer in Node".
12univer-pro-integrate
Integrate Univer Pro (enterprise-grade spreadsheet, document, and presentation engine) into frontend projects. Use when the user needs Univer Pro features including real-time collaboration, XLSX/DOCX import-export, printing, pivot tables, charts, sparklines, shapes, live share, or license management. Also use for setting up UniverLicensePlugin, UniverExchangeClientPlugin, collaboration client plugins, UniverSheetsPrintPlugin, or any Pro-specific integration error. Triggers include "Univer Pro", "collaboration", "import xlsx", "export docx", "print", "pivot table", "chart", "sparkline", "shape", "license", "watermark removal", "UniverLicensePlugin", or "exchange client".
8