Skip to content

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.


  1. Upgrade @revolist/revogrid core to ^4.21.4
  2. Replace all sub-path imports with flat imports from @revolist/revogrid-pro
  3. Replace hardcoded event strings with named constants from @revolist/revogrid-pro
  4. Import revogrid-pro.css in your application entry point
  5. Move plugin configuration from grid.additionalData to direct grid properties
  6. Update custom plugins to extend CorePlugin instead of BasePlugin
  7. Add @revolist/revogrid-pro alongside each standalone product
  8. Move Pivot and Gantt imports to @revolist/pivot and @revolist/gantt
  9. Update Excel export integrations that relied on bundled SheetJS or bundled workbook import parsing when upgrading from 2.0.8
  10. Rename authored Gantt task status fields to workflowStatus and treat the Status column as calculated/read-only
  11. 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
  12. Replace ClipboardJsonPlugin and $rv-parse_ clipboard text with ClipboardPlugin and the smart clipboard document

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)
  • getRowKey and rowKeyProp
  • 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');

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];

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).


v2.0 requires @revolist/revogrid 4.21.4 or later. Earlier core versions are not supported.

Terminal window
npm install @revolist/revogrid@^4.21.4
# or
pnpm add @revolist/revogrid@^4.21.4

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';

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);

The full list of available constants is exported from @revolist/revogrid-pro.


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';

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,
},
};

For framework wrappers, bind the plugin property directly:

<RevoGrid
source={rows}
columns={columns}
plugins={plugins}
pivot={pivot}
pagination={pagination}
/>

Common replacements:

v1.x additionalData keyv2.0 property
additionalData.pivotgrid.pivot
additionalData.paginationgrid.pagination
additionalData.treegrid.tree
additionalData.rowExpandgrid.rowExpand
additionalData.rowAutoSizegrid.rowAutoSize
additionalData.masterRowgrid.masterRow
additionalData.transposegrid.transpose
additionalData.rowContextMenugrid.rowContextMenu
additionalData.columnContextMenugrid.columnContextMenu
additionalData.eventManagergrid.eventManager
additionalData.infinityScrollgrid.infinityScroll
additionalData.cellMergegrid.cellMerge
additionalData.excelgrid.excel
additionalData.hiddenColumnsgrid.hideColumns

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 mutations
  • observeProperty(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
}
}

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.

Terminal window
npm install @revolist/revogrid-pro @revolist/pivot @revolist/gantt
# or
pnpm add @revolist/revogrid-pro @revolist/pivot @revolist/gantt

Keep 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';

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.

AreaIn 2.0.8 and earlierAfter this change
Bundled export librarySheetJS xlsxwrite-excel-file
Default export formatSheetJS-supported formats.xlsx only
Default importWorkbook parsing through bundled dependencyCSV-only import
XLSX importPlugin-ownedApp-owned parser
Provider integrationMostly implicitExplicit provider objects or factories
Formatted workbook outputReconstructed by providerPrepared in context.cellRows

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.

If an app depended on SheetJS output formats, install xlsx in the app and pass the module object into the SheetJS adapter:

Terminal window
pnpm add xlsx
import * 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.

Use ExcelJS when migration requires formatted cellRows, merge spans, row heights, freeze panes, or richer workbook style mapping:

Terminal window
pnpm add exceljs
import 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 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.

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:

  1. Install a parser such as SheetJS, ExcelJS, or read-excel-file.
  2. Parse the file in app code.
  3. Normalize workbook data into columns and rows.
  4. Assign grid.columns, then grid.source.

See Excel Import and Export Libraries for parser tradeoffs and examples.

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.
  • exportTransformers are available on both grid.exportExcel and individual plugin.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.
  • sourceRows preserves pinned segment semantics through rowType (rowPinStart, rgRow, rowPinEnd).
  • cellRows includes 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.

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.


Pro and the standalone product packages are released with the same version number (lockstep semver).

Change typeVersion bump
Breaking API/behavior changeMajor (2.0.0 → 3.0.0)
New plugin or feature (backward-compatible)Minor (2.0.0 → 2.1.0)
Bug fixPatch (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.