JavaScript Data GridMigrate from 8.4 to 9.0

Migrate from Handsontable 8.4 to Handsontable 9.0, released on June 1, 2021.


The purpose of this guide is to make it easier to migrate from v8.4.0 to v9.0.0. In the version 9.0 we have introduced a new formula engine with has completely replaced the previous one. There is a breaking change in the formula API - even in the way the plugin itself is initialized.

Plugin initialization

The plugin uses HyperFormula, which is meant to be passed in as an external dependency every time you want to initialize the plugin. HyperFormula installation guide is available here (opens new window).

Before 9.0 (legacy plugin) After 9.0 (new plugin)
formulas: true import { HyperFormula } from 'hyperformula';

formulas: {
engine: HyperFormula

See other available initialization methods here.

Available methods

Method name Before 9.0 (legacy plugin) After 9.0 (new plugin)
destroy (opens new window) hot.getPlugin('formulas').destroy() Unchanged. This method will destroy the HyperFormula instance only after it is disconnected from all Handsontable instances.
disablePlugin (opens new window) hot.getPlugin('formulas').disablePlugin() Unchanged.
enablePlugin (opens new window) hot.getPlugin('formulas').enablePlugin() Unchanged, but do keep in mind that if you didn't pass in the plugin's config through either updateSettings or during Handsontable initialization this method will not do anything.
getCellValue (opens new window) hot.getPlugin('formulas').getCellValue(row, column) Use base Handsontable API instead, for example hot.getDataAtCell(row, column).
getVariable (opens new window) hot.getPlugin('formulas').getVariable(variableName) "Variables" in the plugin have been replaced by a more powerful alternative, named expressions.
hasComputedCellValue (opens new window) hot.getPlugin('formulas').hasComputedCellValue(row, column) hot.getPlugin('formulas').getCellType(row, column) === 'FORMULA'
isEnabled (opens new window) hot.getPlugin('formulas').isEnabled() Unchanged.
recalculate (opens new window) hot.getPlugin('formulas').recalculate() hot.getPlguin('formulas').engine.rebuildAndRecalculate()
recalculateFull (opens new window) hot.getPlugin('formulas').recalculateFull() hot.getPlguin('formulas').engine.rebuildAndRecalculate()
recalculateOptimized (opens new window) hot.getPlugin('formulas').recalculateOptimized() hot.getPlguin('formulas').engine.rebuildAndRecalculate()
setVariable (opens new window) hot.getPlugin('formulas').setVariable(variableName, value) "Variables" in the plugin have been replaced by a more powerful alternative, named expressions.

Available functions

The list of available functions can be found here (opens new window).

Autofill hooks

To make autofill hooks more consistent and more powerful, beforeAutofill and afterAutofill hooks have had their signatures changed.

Before 9.0.0:

new Handsontable(container, {
  beforeAutofill(start, end, data) {},
  afterAutofill(start, end, data) {}


new Handsontable(container, {
  beforeAutofill(selectionData, sourceRange, targetRange, direction) {
    const start = targetRange.from // used to be `start`
    const end = // used to be `end`
    const data = selectionData // used to be `data`
  afterAutofill(fillData, sourceRange, targetRange, direction) {
    const start = targetRange.from // used to be `start`
    const end = // used to be `end`
    const data = fillData // used to be `data`

In beforeAutofill instead of mutating data, you can now just return a new array of arrays with your desired fill pattern.

Removed plugins

In Handsontable 9.0.0 we removed the following, previously-deprecated plugins:

  • Header Tooltips
  • Observe Changes

Header Tooltips

To implement functionality similar to that of the Header Tooltips plugin, you can utilize the afterGetColHeader and afterGetRowHeader hooks to add a title attribute to the headers. See the snippet below for example implementation.

const onAfterGetHeader = function(index, TH) {
  TH.setAttribute('title', TH.querySelector('span').textContent);

const example = document.querySelector('#tooltip-example');
const hot = new Handsontable(example, {
  data: [
    ['A1', 'B1', 'C1'],
    ['A2', 'B2', 'C2'],
    ['A3', 'B3', 'C3'],
  rowHeights: 23,
  autoColumnSize: true,
  rowHeaders: ['1st', '2nd', '3rd'],
  colHeaders: ['First Column', 'Second Column', 'Third Column'],
  licenseKey: 'non-commercial-and-evaluation',
  afterGetColHeader: onAfterGetHeader,
  afterGetRowHeader: onAfterGetHeader

Observe Changes

The plugin fired the afterChangesObserved hook. Be sure to stop listening to it after updating to version >=9.0.0.