Migrating to 2+
This guide covers every breaking change introduced in v2.0 of @revolist/revogrid-pro and
the standalone product packages, and explains what to update in your codebase.
Quick migration checklist
Section titled “Quick migration checklist”- Upgrade
@revolist/revogridcore to^4.21.4 - Replace all sub-path imports with flat imports from
@revolist/revogrid-pro - Replace hardcoded event strings with named constants from
@revolist/revogrid-pro - Import
revogrid-pro.cssin your application entry point - Move plugin configuration from
grid.additionalDatato direct grid properties - Update custom plugins to extend
CorePlugininstead ofBasePlugin - Add
@revolist/revogrid-proalongside each standalone product - Move Pivot and Gantt imports to
@revolist/pivotand@revolist/gantt - Update Excel export integrations that relied on bundled SheetJS or bundled workbook import parsing when upgrading from
2.0.8 - Rename authored Gantt task
statusfields toworkflowStatusand treat the Status column as calculated/read-only - When upgrading from 2.7 to 2.8, replace model-backed formatting selections and version 1 formatting state with physical coordinates and state version 2
- Replace
ClipboardJsonPluginand$rv-parse_clipboard text withClipboardPluginand the smart clipboard document
2.7 → 2.8 breaking changes
Section titled “2.7 → 2.8 breaking changes”DataGridFormattingPlugin is coordinate-only
Section titled “DataGridFormattingPlugin is coordinate-only”v2.8 removes the formatting compatibility layer completely. The following 2.7 contracts are no longer accepted as formatting operation or state inputs:
- model-backed
{ scope, rows, columns, cells }selections getFormat(model, prop, rowType)getRowKeyandrowKeyProp- formatting runtime state version 1 and row-key preset state
Cell operations now use inclusive, zero-based physical coordinates in the
selected row and column source stores:
plugin.apply({ scope: 'cells', rows: [invoice], columns: [amountColumn], cells: [{ model: invoice, column: amountColumn, rowType: 'rgRow' }],}, moneyFormat);
const format = plugin.getFormat(invoice, 'amount', 'rgRow');plugin.apply({ start: { row: 4, column: 2 }, rowType: 'rgRow', colType: 'rgCol',}, moneyFormat);
const format = plugin.getFormat({ row: 4, column: 2 });Complete-column operations use a separate coordinate target so their format also applies to future rows:
plugin.apply({ scope: 'columns', ranges: { start: 2, end: 4, colType: 'rgCol' },}, moneyFormat);
const format = plugin.getColumnFormat({ column: 2, colType: 'rgCol' });Complete-row operations are symmetrical and also apply to columns added later:
plugin.apply({ scope: 'rows', ranges: { start: 4, end: 6, rowType: 'rgRow' },}, moneyFormat);
const format = plugin.getRowFormat({ row: 4, rowType: 'rgRow' });DataGridFormattingRuntimeState now accepts only version: 3. v2.8 does not
read or infer formatting from version 1 or version 2 state. Applications must migrate
persisted state before assigning it to grid.dataGridFormatting or calling
plugin.setState(). The v3 format stores row, column, rowType, and
colType directly; getRowKey and rowKeyProp are unnecessary because
formatting remains attached to the physical coordinate when source objects are
replaced.
Value formats are now a strict discriminated union. Built-in formats use
{ kind: 'preset', preset: 'currency', ... }; exact Excel-compatible codes use
{ kind: 'code', formatCode: '#,##0.00' }. The ambiguous legacy
{ preset, formatCode } object is rejected. The RevoGrid rich clipboard payload
is correspondingly version 2; version 1 payloads are not inferred as v2.
DataGridFormattingPlugin now auto-installs EventManagerPlugin; remove a
redundant explicit Event Manager entry when formatting is already installed.
Cancel managed edits, including rich clipboard paste, from the cancelable
gridedit event instead of the intercepted core edit event.
Bold cell formatting now uses the standard CSS 700 weight. This also makes
bold formatting imported from Excel visually match the source workbook.
ClipboardJsonPlugin was replaced by ClipboardPlugin
Section titled “ClipboardJsonPlugin was replaced by ClipboardPlugin”v2.8 removes ClipboardJsonPlugin, legacyJsonText, and automatic decoding of
the $rv-parse_ text marker. The marker overloaded text/plain, exposed an
internal serialization convention to external applications, and duplicated the
versioned smart clipboard document.
import { ClipboardJsonPlugin } from '@revolist/revogrid-pro';
grid.plugins = [ClipboardJsonPlugin];import { ClipboardPlugin, DataGridFormattingPlugin,} from '@revolist/revogrid-pro';
// Values and application-defined clipboard formats:grid.plugins = [ClipboardPlugin];
// Or the recommended rich-formatting setup:grid.plugins = [DataGridFormattingPlugin];The smart plugin preserves objects, formulas, formatting, structures, and sparse
multi-range geometry in application/x-revogrid-clipboard+json, with HTML and
plain-text fallbacks for Excel and other applications. Decode any stored
$rv-parse_ values in application code before assigning or pasting them; v2.8
treats marker text literally.
v2.8 also removes the clipboard implementation markers
SMART_CLIPBOARD_PLUGIN, SmartClipboardRuntime, and
isSmartClipboardRuntime. Application code that needs the installed plugin
instance should use the plugin class instead:
const clipboard = (await grid.getPlugins()) .find(plugin => plugin instanceof ClipboardPlugin);Custom Pro plugins can use the equivalent provider-backed lookup:
providers.plugins.getByClass(ClipboardPlugin).
1. Core dependency version
Section titled “1. Core dependency version”v2.0 requires @revolist/revogrid 4.21.4 or later. Earlier core versions are not supported.
npm install @revolist/revogrid@^4.21.4# orpnpm add @revolist/revogrid@^4.21.42. Import paths — flat surface only
Section titled “2. Import paths — flat surface only”v1.x supported sub-path imports that pointed to internal modules. These paths are removed in v2.0. All exports are now available from the single package entry point.
import { commonAggregators } from '@revolist/revogrid-pro/aggregations';import { CorePlugin } from '@revolist/revogrid-pro/core';import { FOCUS_APPLY_EVENT } from '@revolist/revogrid-pro/events';import { createMergedData } from '@revolist/revogrid-pro/utils';import { commonAggregators, CorePlugin, FOCUS_APPLY_EVENT, createMergedData,} from '@revolist/revogrid-pro';3. Event strings → named constants
Section titled “3. Event strings → named constants”v2.0 exports more than 135 named event constants. Replace every hardcoded event string with the corresponding export to benefit from type checking and rename refactoring.
grid.addEventListener('beforecellfocus', handler);grid.addEventListener('beforefocuslost', handler);grid.addEventListener('beforekeydown', handler);grid.addEventListener('aftersourceset', handler);import { EVENT_BEFORE_CELL_FOCUS, EVENT_BEFORE_FOCUS_LOST, BEFORE_KEYDOWN_EVENT, AFTER_SOURCE_SET_EVENT,} from '@revolist/revogrid-pro';
grid.addEventListener(EVENT_BEFORE_CELL_FOCUS, handler);grid.addEventListener(EVENT_BEFORE_FOCUS_LOST, handler);grid.addEventListener(BEFORE_KEYDOWN_EVENT, handler);grid.addEventListener(AFTER_SOURCE_SET_EVENT, handler);The full list of available constants is exported from @revolist/revogrid-pro.
4. CSS — required import
Section titled “4. CSS — required import”Starting in v2.0, the Pro plugin styles are not injected automatically. You must import the stylesheet once in your application entry point.
// main.ts (or your app entry)import '@revolist/revogrid-pro/dist/revogrid-pro.css';<link rel="stylesheet" href="https://cdn.example.com/revogrid-pro/dist/revogrid-pro.css" />Import the stylesheet for each standalone product you use:
import '@revolist/pivot/styles.css';import '@revolist/gantt/styles.css';5. Plugin configuration — direct grid properties
Section titled “5. Plugin configuration — direct grid properties”v2.0 introduces a direct property system for Pro and standalone product plugin configuration. Plugin options
should now be assigned to their own grid property instead of being grouped under
grid.additionalData.
additionalData is deprecated for plugin configuration. It is still read as a legacy fallback during
the v2 migration window, but new code should use direct properties.
This is a breaking change because plugins no longer treat one large shared object as the primary
configuration surface. The old pattern made additionalData grow too quickly: unrelated plugins
shared the same object, and changing one key could notify every plugin observing additionalData.
That could cause unrelated state updates and unnecessary redraws. Direct properties make each plugin
observe only the configuration it owns.
grid.additionalData = { pivot, pagination, tree: { expandedRowIds, }, rowExpand: { expandedRows, }, rowAutoSize: { mode: 'auto', }, eventManager: { applyEventsToSource: true, },};grid.pivot = pivot;grid.pagination = pagination;grid.tree = { expandedRowIds,};grid.rowExpand = { expandedRows,};grid.rowAutoSize = { mode: 'auto',};grid.eventManager = { applyEventsToSource: true,};For framework wrappers, bind the plugin property directly:
<RevoGrid source={rows} columns={columns} plugins={plugins} pivot={pivot} pagination={pagination}/><revo-grid :source="rows" :columns="columns" :plugins="plugins" :pivot="pivot" :pagination="pagination"/>import { Component, NO_ERRORS_SCHEMA } from '@angular/core';import { RevoGrid } from '@revolist/angular-datagrid';
@Component({ selector: 'my-grid', standalone: true, imports: [RevoGrid], // Allows Angular demos to bind RevoGrid plugin props that are not wrapper inputs. schemas: [NO_ERRORS_SCHEMA], template: ` <revo-grid [source]="rows" [columns]="columns" [plugins]="plugins" [pivot]="pivot" [pagination]="pagination" ></revo-grid> `,})export class MyGridComponent {}Common replacements:
v1.x additionalData key | v2.0 property |
|---|---|
additionalData.pivot | grid.pivot |
additionalData.pagination | grid.pagination |
additionalData.tree | grid.tree |
additionalData.rowExpand | grid.rowExpand |
additionalData.rowAutoSize | grid.rowAutoSize |
additionalData.masterRow | grid.masterRow |
additionalData.transpose | grid.transpose |
additionalData.rowContextMenu | grid.rowContextMenu |
additionalData.columnContextMenu | grid.columnContextMenu |
additionalData.eventManager | grid.eventManager |
additionalData.infinityScroll | grid.infinityScroll |
additionalData.cellMerge | grid.cellMerge |
additionalData.excel | grid.excel |
additionalData.hiddenColumns | grid.hideColumns |
6. Custom plugins — extend CorePlugin
Section titled “6. Custom plugins — extend CorePlugin”In v2.0 the recommended base class for all Pro plugins changed from BasePlugin (re-exported from
@revolist/revogrid) to CorePlugin (exported from @revolist/revogrid-pro). CorePlugin adds:
observeAttribute(name, callback)— reacts to DOM attribute mutationsobserveProperty(name, callback)— reacts to direct JS property assignments
import { BasePlugin } from '@revolist/revogrid';
export class MyPlugin extends BasePlugin { constructor(grid, providers) { super(grid, providers); // plugin setup }}import { CorePlugin } from '@revolist/revogrid-pro';
export class MyPlugin extends CorePlugin { constructor(grid, providers) { super(grid, providers); // license banner injected here automatically // plugin setup this.observeProperty('myProp', (value) => { // react to grid.myProp = value }); }}7. Standalone products — install Pro as a dependency
Section titled “7. Standalone products — install Pro as a dependency”Pivot, Gantt, Scheduler, and Kanban require @revolist/revogrid-pro as a runtime dependency.
Install Pro explicitly alongside the products you use.
npm install @revolist/revogrid-pro @revolist/pivot @revolist/gantt# orpnpm add @revolist/revogrid-pro @revolist/pivot @revolist/ganttKeep Pro and the standalone products on the same version (they are released together).
8. Pivot and Gantt use standalone packages
Section titled “8. Pivot and Gantt use standalone packages”In v1.x, Pivot and Gantt plugins were part of @revolist/revogrid-pro. They now live in their
own @revolist/pivot and @revolist/gantt packages.
import { PivotPlugin, PivotConfig } from '@revolist/revogrid-pro';import { GanttPlugin } from '@revolist/revogrid-pro';import { PivotPlugin, type PivotConfig } from '@revolist/pivot';import { GanttPlugin } from '@revolist/gantt';9. Excel export provider changes since 2.0.8
Section titled “9. Excel export provider changes since 2.0.8”ExportExcelPlugin, grid.exportExcel, export-excel, excel-before-import, and excel-before-set keep their public names. The implementation contract changed so workbook-library choices stay app-owned and the default package is lighter.
| Area | In 2.0.8 and earlier | After this change |
|---|---|---|
| Bundled export library | SheetJS xlsx | write-excel-file |
| Default export format | SheetJS-supported formats | .xlsx only |
| Default import | Workbook parsing through bundled dependency | CSV-only import |
| XLSX import | Plugin-owned | App-owned parser |
| Provider integration | Mostly implicit | Explicit provider objects or factories |
| Formatted workbook output | Reconstructed by provider | Prepared in context.cellRows |
Default export
Section titled “Default export”Use the bundled .xlsx provider for normal grid exports:
grid.plugins = [ExportExcelPlugin];
await excel.export({ workbookName: 'report.xlsx', sheetName: 'Report',});The bundled provider now rejects non-.xlsx output:
await excel.export({ workbookName: 'report.xlsb',});
await excel.export({ writingOptions: { bookType: 'xlsb' },});Use SheetJS, ExcelJS, workbook-module, or a custom provider when another workbook format is required.
App-owned SheetJS
Section titled “App-owned SheetJS”If an app depended on SheetJS output formats, install xlsx in the app and pass the module object into the SheetJS adapter:
pnpm add xlsximport * as XLSX from 'xlsx';import { createSheetJsExcelExportProvider } from '@revolist/revogrid-pro';
grid.exportExcel = { exportProvider: createSheetJsExcelExportProvider(XLSX),};The SheetJS adapter writes plain context.rows data. It is the compatibility path for apps that want SheetJS-owned workbook writing.
App-owned ExcelJS
Section titled “App-owned ExcelJS”Use ExcelJS when migration requires formatted cellRows, merge spans, row heights, freeze panes, or richer workbook style mapping:
pnpm add exceljsimport ExcelJS from 'exceljs';import { createExcelJsExcelExportProvider } from '@revolist/revogrid-pro';
grid.exportExcel = { exportProvider: createExcelJsExcelExportProvider(ExcelJS),};The ExcelJS adapter does not add ExcelJS to RevoGrid Pro dependencies. Your application owns the dependency and bundle cost.
Custom providers
Section titled “Custom providers”Custom providers should consume the prepared provider context instead of reading rendered grid rows:
const provider = { id: 'custom', async export(context) { await writeWorkbook(context.cellRows, { fileName: context.workbookName, sheetName: context.sheetName, metadata: context.exportMetadata, }); },};Use context.cellRows when the provider needs formatted cells, grouped headers, formulas, or merge spans. Use context.rows only for plain row-object output.
CSV-only default import
Section titled “CSV-only default import”Default import now accepts CSV files. It reads files with FileReader.readAsText, dispatches excel-before-import, maps rows, dispatches excel-before-set, then updates the grid source unless either event is prevented.
.xlsx and .xls parsing is no longer bundled. For workbook uploads:
- Install a parser such as SheetJS, ExcelJS, or read-excel-file.
- Parse the file in app code.
- Normalize workbook data into
columnsandrows. - Assign
grid.columns, thengrid.source.
See Excel Import and Export Libraries for parser tradeoffs and examples.
Feature-owned helpers
Section titled “Feature-owned helpers”Feature-owned export helpers are still exported from Pro:
- Formula helper for exporting workbook formulas.
- Cell merge and grouped column transforms run automatically.
- Date, numeral, and select helpers are explicit utilities for optional column packages.
exportTransformersare available on bothgrid.exportExceland individualplugin.export()calls.
Provider contexts now include cellRows, sourceRows, headerRowsCount, gridDerivedOptions, and exportMetadata. Custom providers that need richer export output should consume those fields instead of reconstructing workbook state from rows.
When migrating custom providers, keep these rules in mind:
- Export data is prepared from data stores and grid source fallbacks, not rendered DOM rows.
sourceRowspreserves pinned segment semantics throughrowType(rowPinStart,rgRow,rowPinEnd).cellRowsincludes generated headers and formatted provider cells; its data rows stay in pinned-top, body, pinned-bottom order.- Missing pinned sources are empty. If a body data store is not initialized, export falls back to
grid.source.
Gantt Status is now calculated
Section titled “Gantt Status is now calculated”The Gantt Status field now follows Microsoft Project-style reporting semantics and is read-only. Existing workflow values move to workflowStatus:
// Before{ id: 'task-1', status: 'in-progress' }
// After{ id: 'task-1', workflowStatus: 'in-progress' }Legacy source and project JSON ingestion maps status to workflowStatus only when workflowStatus is absent. Serialization writes only workflowStatus. Remove code that edits the Status column and use the editable Workflow Status column or task-form field instead.
Set a project reporting date when deterministic results matter:
grid.gantt = { ...project, statusDate: '2026-04-08',};When omitted, statusDate defaults to today. Excel export now contains separate Status and Workflow Status columns, and label overrides are split between labels.status and labels.workflowStatus.
Versioning strategy
Section titled “Versioning strategy”Pro and the standalone product packages are released with the same version number (lockstep semver).
| Change type | Version bump |
|---|---|
| Breaking API/behavior change | Major (2.0.0 → 3.0.0) |
| New plugin or feature (backward-compatible) | Minor (2.0.0 → 2.1.0) |
| Bug fix | Patch (2.0.0 → 2.0.1) |
The RevoGrid core package (@revolist/revogrid) versions independently — always check its
changelog when upgrading core alongside the Pro product packages.