# Migrating to 2+
URL: https://pro.rv-grid.com/guides/migration-v2/
Source: src/content/docs/guides/migration-v2.mdx
Description: Step-by-step guide for upgrading to RevoGrid Pro 2+
This guide covers every breaking change introduced in **v2.0** of `@revolist/revogrid-pro` and
`@revolist/revogrid-enterprise`, and explains what to update in your codebase.

v2.0 is a **major release** with breaking changes in imports, plugin configuration, plugin
authoring, CSS setup, and the Enterprise package structure. Read through the checklist below before
upgrading.

---

## Quick migration checklist

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` as a dependency when using Enterprise
8. Move Pivot and Gantt imports to `@revolist/revogrid-enterprise`
9. Update Excel export integrations that relied on bundled SheetJS or bundled workbook import parsing when upgrading from `2.0.8`

---

## 1. Core dependency version

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

```bash
npm install @revolist/revogrid@^4.21.4
# or
pnpm add @revolist/revogrid@^4.21.4
```

---

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

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

```ts
import {
  commonAggregators,
  CorePlugin,
  FOCUS_APPLY_EVENT,
  createMergedData,
} from '@revolist/revogrid-pro';
```

---

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

```ts
grid.addEventListener('beforecellfocus', handler);
grid.addEventListener('beforefocuslost', handler);
grid.addEventListener('beforekeydown', handler);
grid.addEventListener('aftersourceset', handler);
```

```ts
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

Starting in v2.0, the Pro plugin styles are **not** injected automatically. You must import the
stylesheet once in your application entry point.

```ts
// main.ts (or your app entry)
import '@revolist/revogrid-pro/dist/revogrid-pro.css';
```

```html
<link rel="stylesheet" href="https://cdn.example.com/revogrid-pro/dist/revogrid-pro.css" />
```

If you are also using Enterprise, import its stylesheet separately:

```ts
import '@revolist/revogrid-enterprise/dist/revogrid-enterprise.css';
```

---

## 5. Plugin configuration — direct grid properties

v2.0 introduces a direct property system for Pro and Enterprise 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.

```ts
grid.additionalData = {
  pivot,
  pagination,
  tree: {
    expandedRowIds,
  },
  rowExpand: {
    expandedRows,
  },
  rowAutoSize: {
    mode: 'auto',
  },
  eventManager: {
    applyEventsToSource: true,
  },
};
```

```ts
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:

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

```vue
<revo-grid
  :source="rows"
  :columns="columns"
  :plugins="plugins"
  :pivot="pivot"
  :pagination="pagination"
/>
```

```ts
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` |

Core grid inputs such as `source`, `columns`, `plugins`, `theme`, `stretch`, `rowDefinitions`, and
`rowHeaders` are already direct RevoGrid properties. Keep binding those directly as before.

---

## 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 mutations
- `observeProperty(name, callback)` — reacts to direct JS property assignments

```ts
import { BasePlugin } from '@revolist/revogrid';

export class MyPlugin extends BasePlugin {
  constructor(grid, providers) {
    super(grid, providers);
    // plugin setup
  }
}
```

```ts
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. Enterprise — install Pro as a dependency

`@revolist/revogrid-enterprise` now **requires** `@revolist/revogrid-pro` as a runtime dependency.
If you only had Enterprise installed, add Pro explicitly.

```bash
npm install @revolist/revogrid-pro @revolist/revogrid-enterprise
# or
pnpm add @revolist/revogrid-pro @revolist/revogrid-enterprise
```

Ensure both packages are on the **same version** (they are always released together).

---

## 8. Pivot and Gantt moved to Enterprise

In v1.x, Pivot and Gantt plugins were part of `@revolist/revogrid-pro`. They now live exclusively
in `@revolist/revogrid-enterprise`.

```ts
import { PivotPlugin, PivotConfig } from '@revolist/revogrid-pro';
import { GanttPlugin }              from '@revolist/revogrid-pro';
```

```ts
import { PivotPlugin, PivotConfig } from '@revolist/revogrid-enterprise';
import { GanttPlugin }              from '@revolist/revogrid-enterprise';
```

---

## 9. Excel export provider changes since 2.0.8

This is a breaking change for applications upgrading from `@revolist/revogrid-pro` `2.0.8` or earlier if they relied on bundled SheetJS, non-`.xlsx` default export output, or bundled `.xlsx` / `.xls` import parsing.

`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

Use the bundled `.xlsx` provider for normal grid exports:

```ts
grid.plugins = [ExportExcelPlugin];

await excel.export({
  workbookName: 'report.xlsx',
  sheetName: 'Report',
});
```

The bundled provider now rejects non-`.xlsx` output:

```ts
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

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

```sh
pnpm add xlsx
```

```ts
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.

### App-owned ExcelJS

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

```sh
pnpm add exceljs
```

```ts
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

Custom providers should consume the prepared provider context instead of reading rendered grid rows:

```ts
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

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](/guides/excel-export/excel-import-export-libraries/) for parser tradeoffs and examples.

### 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.
- `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`.

---

## Versioning strategy

Pro and Enterprise are always 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 Pro/Enterprise.
