docs(skills): add Handsontable and HyperFormula skills

This commit is contained in:
s
2026-06-18 10:23:58 +02:00
parent 3429a7a2a6
commit 0ac3ff4511
12 changed files with 1774 additions and 0 deletions
+606
View File
@@ -0,0 +1,606 @@
---
name: handsontable
description: >
Use this skill whenever the user asks about Handsontable — a JavaScript data grid component with
spreadsheet-like UX. Triggers include: mentions of "handsontable", "HotTable", "data grid",
"@handsontable/react-wrapper", spreadsheet component in React/Angular/Vue, HyperFormula formulas
inside a grid, cell types (dropdown, checkbox, date, numeric) in a grid context, or questions
about Handsontable theming, plugins, hooks, configuration options, or column/row features. Also
trigger when the user wants to add an editable spreadsheet-like table to a web app, or asks about
copy/paste, sorting, filtering, frozen rows/columns, merged cells, or context menus in a grid.
This skill covers Handsontable used with any framework (React, Angular, Vue 3, vanilla JS) and
HyperFormula as the Formulas plugin engine inside Handsontable. Do NOT use this skill for
headless/standalone HyperFormula usage without Handsontable — that is covered by the separate
"hyperformula" skill.
---
# Handsontable
Handsontable is a JavaScript **data grid component** (not a full spreadsheet application) that
brings spreadsheet-like UX to web apps: cell editing, copy/paste, sorting, filtering, formulas,
keyboard navigation, context menus, merged cells, frozen rows/columns, conditional formatting, data
validation, pagination, and 400+ built-in formulas via HyperFormula.
- **Latest version:** 17.1.0 (May 2026)
- **Frameworks:** Vanilla JS/TS, React (`@handsontable/react-wrapper`), Angular (`@handsontable/angular-wrapper`), Vue 3 (`@handsontable/vue3`)
- **React wrapper requires:** React 18+
- **License:** Dual — free for non-commercial use (`licenseKey: 'non-commercial-and-evaluation'`), paid for commercial. Per-developer annual license, offline validation (no server connection). Tiers: Hobby (free, non-commercial), Trial (free 45 days), Standard (from $999/yr), Priority (from $1,299/yr), Enterprise (custom). See [Pricing](https://handsontable.com/pricing).
Always check `references/docs-map.md` (in this skill folder) for the full organized link directory
when you need to point the user to specific documentation or need to look up more info.
### What this skill does NOT cover
- **Standalone HyperFormula** (headless formula engine without a grid UI) — use the "hyperformula" skill instead.
- **Other data grid libraries** (AG Grid, TanStack Table, etc.).
- **Full spreadsheet applications** — Handsontable is a component you embed, not a standalone app like Google Sheets.
---
## React Quick Start (Recommended)
### Install
```bash
npm install handsontable @handsontable/react-wrapper
```
### Minimal working example
```jsx
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
import 'handsontable/styles/handsontable.min.css';
import 'handsontable/styles/ht-theme-main.min.css';
registerAllModules();
const MyGrid = () => (
<HotTable
themeName="ht-theme-main"
data={[
['', 'Tesla', 'Volvo', 'Toyota', 'Ford'],
['2019', 10, 11, 12, 13],
['2020', 20, 11, 14, 13],
['2021', 30, 15, 12, 13],
]}
colHeaders={true}
rowHeaders={true}
height="auto"
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
/>
);
export default MyGrid;
```
Key points:
- `registerAllModules()` registers every built-in plugin. To reduce bundle size, import only what
you need — see [Modules guide](https://handsontable.com/docs/react-data-grid/modules/).
- `height` is required (or the grid won't render). Use `"auto"`, a pixel number, or a CSS string.
- All Handsontable configuration options are passed as props on `<HotTable>`.
- Full installation guide: https://handsontable.com/docs/react-data-grid/installation/
---
## Vanilla JS Quick Start
### Install
```bash
npm install handsontable
```
### CDN (jsDelivr)
```html
<script src="https://cdn.jsdelivr.net/npm/handsontable/dist/handsontable.full.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/handsontable/styles/handsontable.min.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/handsontable/styles/ht-theme-main.min.css" />
```
To pin a specific version, add `@17.1` after `handsontable` in the URL (e.g.,
`handsontable@17.1/dist/handsontable.full.min.js`).
### Minimal working example
```js
import Handsontable from 'handsontable';
import 'handsontable/styles/handsontable.min.css';
import 'handsontable/styles/ht-theme-main.min.css';
const container = document.getElementById('grid');
new Handsontable(container, {
data: [
['', 'Tesla', 'Volvo', 'Toyota', 'Ford'],
['2019', 10, 11, 12, 13],
['2020', 20, 11, 14, 13],
['2021', 30, 15, 12, 13],
],
colHeaders: true,
rowHeaders: true,
height: 'auto',
themeName: 'ht-theme-main',
autoWrapRow: true,
autoWrapCol: true,
licenseKey: 'non-commercial-and-evaluation',
});
```
Full JS docs: https://handsontable.com/docs/javascript-data-grid/installation/
---
## Other Frameworks
### Angular (v1719)
```bash
npm install handsontable @handsontable/angular-wrapper
```
The Angular wrapper was modernized in Handsontable v17.1 to align with Angular 1719, simplifying setup and reducing dependencies. Earlier Angular versions are no longer the target — upgrade Angular first if you're below v17.
Docs: https://handsontable.com/docs/angular-data-grid/installation/
### Vue 3
```bash
npm install handsontable @handsontable/vue3
```
Docs: https://handsontable.com/docs/react-data-grid/vue3-installation/
All framework wrappers share the same version number as the core library and expose the same
configuration options. The React examples in this skill translate directly — just use the
framework's component syntax. Note: Vue 2 (`@handsontable/vue`) is deprecated — use Vue 3.
---
## Theming: Light / Dark / Auto
Handsontable v15+ includes a built-in theme system. Three themes ship out of the box: **main**
(default, spreadsheet-like), **horizon** (clean, analytics-focused), **classic** (legacy
replacement).
### CSS file approach (simplest)
Import the base stylesheet plus a theme:
```js
import 'handsontable/styles/handsontable.min.css';
import 'handsontable/styles/ht-theme-main.min.css';
```
Then set the theme on the grid:
```jsx
<HotTable themeName="ht-theme-main" /* ... */ />
```
**Dark mode:**
- System preference (auto): `themeName="ht-theme-main-dark-auto"`
- Forced dark: `themeName="ht-theme-main-dark"`
Replace `main` with `horizon` or `classic` for other themes.
### Theme API approach (runtime switching)
```js
import { mainTheme, registerTheme } from 'handsontable/themes';
const theme = registerTheme(mainTheme)
.setColorScheme('auto') // 'light' | 'dark' | 'auto'
.setDensityType('comfortable'); // 'compact' | 'default' | 'comfortable'
```
Then pass it as a prop:
```jsx
<HotTable theme={theme} /* ... */ />
```
### CDN theme files
```html
<!-- Theme CSS (includes light and dark mode support) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/handsontable/styles/ht-theme-main.min.css" />
```
In v17, dark mode is controlled via `themeName` or the Theme API — there are no separate `-dark` or
`-dark-auto` CSS files. Load the base theme CSS above and set the mode at runtime.
For CSS variable customization, the Theme Builder, Figma design system, and 200+ design tokens, see:
- [Themes guide](https://handsontable.com/docs/react-data-grid/themes/)
- [Theme customization](https://handsontable.com/docs/react-data-grid/theme-customization/)
- [Theme Builder tool](https://handsontable.com/theme-builder)
---
## Common Configuration Patterns
All options below are passed as props on `<HotTable>` (React) or in the config object (vanilla JS).
For the full options reference: https://handsontable.com/docs/react-data-grid/api/options/
### Data binding
```jsx
// Array of arrays
data={[['A1', 'B1'], ['A2', 'B2']]}
// Array of objects
data={[{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]}
columns={[{ data: 'id' }, { data: 'name' }]}
```
Docs: https://handsontable.com/docs/react-data-grid/binding-to-data/
### Column & row headers
```jsx
colHeaders={['ID', 'Name', 'Price']} // custom labels, or {true} for A, B, C...
rowHeaders={true} // 1, 2, 3... or pass an array
```
### Column types (cell types)
Set via the `columns` array or `cells` function. Built-in types:
- `text` (default), `numeric`, `date`, `time`, `checkbox`, `select`, `dropdown`,
`autocomplete`, `password`, `handsontable` (nested grid), `multiselect` (v17+)
```jsx
columns={[
{ data: 'name', type: 'text' },
{ data: 'price', type: 'numeric', numericFormat: { pattern: '$0,0.00' } },
{ data: 'active', type: 'checkbox' },
{ data: 'category', type: 'dropdown', source: ['A', 'B', 'C'] },
]}
```
Full cell types reference: https://handsontable.com/docs/react-data-grid/cell-type/
### Sorting & filtering
```jsx
columnSorting={true} // single-column sort
// or
multiColumnSorting={true} // multi-column sort
filters={true} // enable column filters
dropdownMenu={true} // column header menu with filter UI
```
### Frozen rows/columns
```jsx
fixedRowsTop={1}
fixedRowsBottom={1}
fixedColumnsStart={2}
```
### Other common options
```jsx
readOnly={true} // entire grid read-only (or per-cell/column)
contextMenu={true} // right-click menu
mergeCells={[{ row: 0, col: 0, rowspan: 2, colspan: 2 }]}
manualColumnResize={true}
manualRowResize={true}
stretchH="all" // stretch columns to fill width: 'none' | 'last' | 'all'
```
### Per-column config with HotColumn (React)
```jsx
import { HotTable, HotColumn } from '@handsontable/react-wrapper';
<HotTable data={data} licenseKey="non-commercial-and-evaluation">
<HotColumn title="Name" data="name" />
<HotColumn title="Active" data="active" type="checkbox" />
</HotTable>
```
Docs: https://handsontable.com/docs/react-data-grid/hot-column/
---
## HyperFormula Integration (Formulas Plugin)
HyperFormula powers Handsontable's Formulas plugin, providing 400+ spreadsheet functions (SUM,
AVERAGE, IF, VLOOKUP, etc.). This section covers using HyperFormula **inside** Handsontable only.
### Install
```bash
npm install hyperformula
```
> **Note:** Starting in Handsontable v18, HyperFormula will no longer be bundled. Install it
> separately and pass it to the Formulas plugin.
### CDN
```html
<script src="https://cdn.jsdelivr.net/npm/hyperformula/dist/hyperformula.full.min.js"></script>
```
### Simple setup (auto-created instance)
Pass the `HyperFormula` class directly — Handsontable creates an instance automatically:
```jsx
import { HyperFormula } from 'hyperformula';
<HotTable
data={[
['10', '20', '=SUM(A1:B1)'],
['30', '40', '=SUM(A2:B2)'],
]}
formulas={{ engine: HyperFormula }}
colHeaders={true}
licenseKey="non-commercial-and-evaluation"
/>
```
### External instance (for multi-sheet or shared engine)
Create a HyperFormula instance with the `'internal-use-in-handsontable'` license key:
```jsx
import { HyperFormula } from 'hyperformula';
const hfInstance = HyperFormula.buildEmpty({
licenseKey: 'internal-use-in-handsontable',
});
// Sheet 1
<HotTable
data={data1}
formulas={{ engine: hfInstance, sheetName: 'Sheet1' }}
licenseKey="non-commercial-and-evaluation"
/>
// Sheet 2 — shares the same engine, enabling cross-sheet references
<HotTable
data={data2}
formulas={{ engine: hfInstance, sheetName: 'Sheet2' }}
licenseKey="non-commercial-and-evaluation"
/>
```
Cross-sheet formula example: `=SUM(Sheet1!A:A)`
### Named expressions
```jsx
formulas={{
engine: HyperFormula,
namedExpressions: [
{ name: 'TAX_RATE', expression: 0.21 },
],
}}
```
Use in cells: `=A1 * TAX_RATE`
### Listening for formula changes
```jsx
<HotTable
formulas={{ engine: HyperFormula }}
afterFormulasValuesUpdate={(changes) => {
changes.forEach((c) => console.log(c.address, c.newValue));
}}
/>
```
### Known limitations
- Formulas don't work with nested object data.
- Moving rows/columns with formulas requires the ManualRowMove / ManualColumnMove plugins (not IndexMapper).
- `getSourceData()` operates on physical indexes; formulas use visual indexes.
Full guide: https://handsontable.com/docs/react-data-grid/formula-calculation/
HyperFormula functions list: https://hyperformula.handsontable.com/docs/guide/built-in-functions.html
HyperFormula version compatibility table: https://handsontable.com/docs/react-data-grid/formula-calculation/#hyperformula-version-support
---
## Server-side data with DataProvider (v17.1+)
The **DataProvider plugin** (new in v17.1) wires the grid up to a remote data source so rows are fetched, sorted, and mutated server-side instead of held in memory. Use it for datasets too large to load up front, or when the source of truth lives in a backend.
The `dataProvider` option is an object with five required keys: a row-id resolver, a paginated `fetchRows` callback, and three mutation callbacks. For a read-only grid, stub the mutation callbacks with `async () => {}` — they must still be present.
```jsx
<HotTable
colHeaders={['ID', 'Name', 'Email']}
pagination={{ pageSize: 25 }}
columnSorting={true}
emptyDataState={true}
height={360}
licenseKey="non-commercial-and-evaluation"
dataProvider={{
// Required: how to extract a stable id from each row
rowId: 'id',
// Required: paginated fetch. `sort` is null when no column is sorted.
// Second arg carries an AbortSignal — pass it to fetch() so the plugin
// can cancel superseded requests when the user pages/sorts quickly.
async fetchRows({ page, pageSize, sort }, { signal }) {
const params = new URLSearchParams({ page, pageSize });
if (sort) {
// sort = { prop: string, order: 'asc' | 'desc' }
params.set('sortBy', sort.prop);
params.set('order', sort.order);
}
const res = await fetch(`/api/users?${params}`, { signal });
const { rows, totalRows } = await res.json();
return { rows, totalRows };
},
// Required. Stub with async () => {} if your grid is read-only.
// The plugin auto-refetches the current page after each callback resolves.
// See the plugin API ref for the exact payload shapes.
onRowsCreate: async () => {},
onRowsUpdate: async () => {},
onRowsRemove: async () => {},
}}
/>
```
### Loading and error UI
The plugin fires three hooks you can wire up as `<HotTable>` props for loading indicators and error surfaces:
- `beforeDataProviderFetch(params)` — fires before each fetch. `params.skipLoading` is set when the plugin wants to suppress your loading indicator (e.g., during a quick refetch).
- `afterDataProviderFetch(result)` — fires after a successful fetch.
- `afterDataProviderFetchError(error)` — fires when `fetchRows` throws or returns a rejected promise.
### Companion options
The plugin is built to pair with `pagination` (paginates server-side), `columnSorting` (single-column server-side sort), and `emptyDataState` (loading + empty state UI). Enable all three when you use DataProvider.
### Authoritative references
- Guide: https://handsontable.com/docs/react-data-grid/server-side-data-fetching/
- Recipe (REST API): https://handsontable.com/docs/react-data-grid/recipes/data-management/load-data-rest-api/
- Plugin API: https://handsontable.com/docs/react-data-grid/api/data-provider/
## Notifications (v17.1+)
The **Notification plugin** (new in v17.1) shows non-blocking toast notifications anchored to the grid — useful for confirming saves, surfacing validation errors, or signaling background sync state. Enable with `notifications: true` and trigger via `hot.getPlugin('notifications').showMessage(...)`. See the plugin guide for placement, severity levels, and auto-dismiss timing: https://handsontable.com/docs/react-data-grid/notification/
---
## Events & Hooks
Handsontable hooks are passed as props on `<HotTable>`:
```jsx
<HotTable
afterChange={(changes, source) => {
if (source !== 'loadData') {
console.log('Cell changed:', changes);
}
}}
beforeChange={(changes, source) => {
// Return false to cancel the edit
}}
afterSelection={(row, col, row2, col2) => {
console.log('Selected:', row, col, 'to', row2, col2);
}}
/>
```
There are 100+ hooks available. Full reference: https://handsontable.com/docs/react-data-grid/api/hooks/
Guide: https://handsontable.com/docs/react-data-grid/events-and-hooks/
---
## Accessing the Instance (Ref)
Use a ref to call Handsontable's core methods:
```jsx
import { useRef } from 'react';
const MyGrid = () => {
const hotRef = useRef(null);
const handleClick = () => {
const hot = hotRef.current?.hotInstance;
if (hot) {
console.log(hot.getData()); // get all data
hot.selectCell(0, 0); // select a cell
}
};
return (
<>
<HotTable ref={hotRef} /* ...options */ />
<button onClick={handleClick}>Get Data</button>
</>
);
};
```
Core API reference: https://handsontable.com/docs/react-data-grid/api/core/
---
## Performance & Large Datasets
Handsontable virtualizes rendering automatically — only visible rows and columns are in the DOM, so
grids with 10k100k+ rows perform well out of the box. For bulk programmatic updates, wrap mutations
in `batch()` to defer re-rendering until all changes are applied:
```jsx
hotRef.current.hotInstance.batch(() => {
// set many cells, add rows, etc.
});
```
For further tuning (disabling auto-size, reducing plugin overhead), see:
- [Performance guide](https://handsontable.com/docs/react-data-grid/performance/)
- [Batch operations](https://handsontable.com/docs/react-data-grid/batch-operations/)
- [Bundle size optimization](https://handsontable.com/docs/react-data-grid/bundle-size/)
---
## Recipes (v17+)
Handsontable v17 introduced a Recipes section in the docs — ready-made patterns for common use cases
(data validation workflows, dynamic column generation, etc.). Check the recipes index before building
something from scratch: https://handsontable.com/docs/react-data-grid/recipes/
---
## Common Pitfalls
- **Forgetting `height`**: The grid won't render without a `height` prop. Use `"auto"`, a pixel value, or a CSS string.
- **Not filtering `loadData` in `afterChange`**: The `afterChange` hook fires on initial data load with `source === 'loadData'`. Always check the source to avoid infinite loops when syncing changes back to state.
- **Using the old wrapper packages**: v17 removed `@handsontable/react` and `@handsontable/angular`. Use `@handsontable/react-wrapper` and `@handsontable/angular-wrapper`.
- **Using legacy CSS imports**: `handsontable.full.min.css` was removed in v17. Use `handsontable/styles/handsontable.min.css` plus a theme file.
- **Formulas with nested object data**: HyperFormula formulas don't work when `data` is an array of nested objects — use flat objects or arrays of arrays.
- **ExportFile `columnHeaders` renamed**: In v17.1 the ExportFile plugin's `columnHeaders` option was renamed to `colHeaders` to match the table-level option. Update any `exportAsString` / `exportAsBlob` / `downloadFile` calls that pass `columnHeaders: ...`.
---
## Version Awareness
Handsontable docs are versioned. The latest docs live at `/docs/react-data-grid/` (which redirects
to the current version). To link to a specific version, use `/docs/17.0/react-data-grid/`.
When helping a user, check which version they are on — breaking changes between major versions are
common. Point them to the relevant migration guide if they're upgrading.
For the full organized directory of documentation links, read `references/docs-map.md` in this
skill's folder.
### v17.1 changes (latest, May 2026)
- **New plugins:** DataProvider (server-side row loading via `dataProvider` option), Notification (toast notifications).
- **NestedHeaders rowspan:** column headers can now span multiple header rows.
- **ExportFile:** XLSX export added; the `columnHeaders` option was renamed to `colHeaders` (see Common Pitfalls).
- **Angular wrapper:** modernized for Angular 1719; simpler setup, fewer deps.
- **Touch:** long-press now opens the context menu on touch devices.
- **TypeScript:** `dateFormat` option now accepts `Intl.DateTimeFormatOptions`.
- No removals or deprecations in v17.1.
### v17.0 Breaking Changes
- Removed legacy wrapper packages (`@handsontable/react`, `@handsontable/angular`). Use
`@handsontable/react-wrapper` and `@handsontable/angular-wrapper`.
- Removed legacy CSS (`handsontable.full.min.css`). Use `handsontable/styles/` imports.
- Removed core-js from dependencies.
- Removed the PersistentState plugin.
- Deprecated bundled HyperFormula (will require separate install in v18).
- Deprecated numbro.js, Pikaday, moment.js, DOMPurify — use native alternatives.
Migration guide: https://handsontable.com/docs/react-data-grid/migration-from-16.2-to-17.0/
@@ -0,0 +1,231 @@
# Handsontable Documentation Map
> Last verified: May 2026 · Aligned with Handsontable 17.1.0
Organized link directory for all Handsontable and HyperFormula (in-grid) documentation. Use these
to point users to the right page. Links default to the React docs; replace `react-data-grid` with
`javascript-data-grid`, `angular-data-grid`, or prefix with `vue3-` for other frameworks.
## Getting Started
- Installation: https://handsontable.com/docs/react-data-grid/installation/
- Demo: https://handsontable.com/docs/react-data-grid/demo/
- Binding to data: https://handsontable.com/docs/react-data-grid/binding-to-data/
- Server-side data fetching (DataProvider, v17.1+): https://handsontable.com/docs/react-data-grid/server-side-data-fetching/
- Saving data: https://handsontable.com/docs/react-data-grid/saving-data/
- Configuration options guide: https://handsontable.com/docs/react-data-grid/configuration-options/
- Grid size: https://handsontable.com/docs/react-data-grid/grid-size/
- Instance methods: https://handsontable.com/docs/react-data-grid/instance-methods/
- Events and hooks: https://handsontable.com/docs/react-data-grid/events-and-hooks/
- License key: https://handsontable.com/docs/react-data-grid/license-key/
- Redux integration: https://handsontable.com/docs/react-data-grid/redux/
## Styling & Themes
- Themes guide: https://handsontable.com/docs/react-data-grid/themes/
- Design system (Figma): https://handsontable.com/docs/react-data-grid/handsontable-design-system/
- Theme customization (CSS vars, tokens): https://handsontable.com/docs/react-data-grid/theme-customization/
- Legacy style (pre-v15): https://handsontable.com/docs/react-data-grid/legacy-style/
- Theme Builder tool: https://handsontable.com/theme-builder
- Figma Theme Generator: https://github.com/handsontable/handsontable-figma
## Columns
- HotColumn component (React): https://handsontable.com/docs/react-data-grid/hot-column/
- Column headers: https://handsontable.com/docs/react-data-grid/column-header/
- Column groups (nested headers): https://handsontable.com/docs/react-data-grid/column-groups/
- Column hiding: https://handsontable.com/docs/react-data-grid/column-hiding/
- Column moving: https://handsontable.com/docs/react-data-grid/column-moving/
- Column freezing: https://handsontable.com/docs/react-data-grid/column-freezing/
- Column widths: https://handsontable.com/docs/react-data-grid/column-width/
- Column summary: https://handsontable.com/docs/react-data-grid/column-summary/
- Column virtualization: https://handsontable.com/docs/react-data-grid/column-virtualization/
- Column menu (dropdown): https://handsontable.com/docs/react-data-grid/column-menu/
- Column filter: https://handsontable.com/docs/react-data-grid/column-filter/
## Rows
- Row headers: https://handsontable.com/docs/react-data-grid/row-header/
- Row parent-child (nested rows): https://handsontable.com/docs/react-data-grid/row-parent-child/
- Row hiding: https://handsontable.com/docs/react-data-grid/row-hiding/
- Row moving: https://handsontable.com/docs/react-data-grid/row-moving/
- Row freezing: https://handsontable.com/docs/react-data-grid/row-freezing/
- Row heights: https://handsontable.com/docs/react-data-grid/row-height/
- Row virtualization: https://handsontable.com/docs/react-data-grid/row-virtualization/
- Rows sorting: https://handsontable.com/docs/react-data-grid/rows-sorting/
- Rows pagination: https://handsontable.com/docs/react-data-grid/rows-pagination/
- Row trimming: https://handsontable.com/docs/react-data-grid/row-trimming/
- Row pre-populating: https://handsontable.com/docs/react-data-grid/row-prepopulating/
## Cell Features
- Clipboard (copy/paste): https://handsontable.com/docs/react-data-grid/basic-clipboard/
- Selection: https://handsontable.com/docs/react-data-grid/selection/
- Merge cells: https://handsontable.com/docs/react-data-grid/merge-cells/
- Conditional formatting: https://handsontable.com/docs/react-data-grid/conditional-formatting/
- Text alignment: https://handsontable.com/docs/react-data-grid/text-alignment/
- Disabled cells: https://handsontable.com/docs/react-data-grid/disabled-cells/
- Comments: https://handsontable.com/docs/react-data-grid/comments/
- Autofill values: https://handsontable.com/docs/react-data-grid/autofill-values/
- Formatting cells: https://handsontable.com/docs/react-data-grid/formatting-cells/
## Cell Functions
- Cell functions overview: https://handsontable.com/docs/react-data-grid/cell-function/
- Cell renderer: https://handsontable.com/docs/react-data-grid/cell-renderer/
- Cell editor: https://handsontable.com/docs/react-data-grid/cell-editor/
- Cell validator: https://handsontable.com/docs/react-data-grid/cell-validator/
- Custom cells (v17+): https://handsontable.com/docs/react-data-grid/custom-cells/
## Cell Types
- Cell type overview: https://handsontable.com/docs/react-data-grid/cell-type/
- Numeric: https://handsontable.com/docs/react-data-grid/numeric-cell-type/
- Date: https://handsontable.com/docs/react-data-grid/date-cell-type/
- Time: https://handsontable.com/docs/react-data-grid/time-cell-type/
- Checkbox: https://handsontable.com/docs/react-data-grid/checkbox-cell-type/
- Select: https://handsontable.com/docs/react-data-grid/select-cell-type/
- Dropdown: https://handsontable.com/docs/react-data-grid/dropdown-cell-type/
- Autocomplete: https://handsontable.com/docs/react-data-grid/autocomplete-cell-type/
- MultiSelect (v17+): https://handsontable.com/docs/react-data-grid/multiselect-cell-type/
- Password: https://handsontable.com/docs/react-data-grid/password-cell-type/
- Handsontable (nested grid): https://handsontable.com/docs/react-data-grid/handsontable-cell-type/
## Formulas (HyperFormula in Handsontable)
- Formula calculation guide: https://handsontable.com/docs/react-data-grid/formula-calculation/
- Formulas plugin API: https://handsontable.com/docs/react-data-grid/api/formulas/
- HyperFormula built-in functions list: https://hyperformula.handsontable.com/docs/guide/built-in-functions.html
- HyperFormula configuration options: https://hyperformula.handsontable.com/docs/guide/configuration-options.html
- HyperFormula custom functions: https://hyperformula.handsontable.com/docs/guide/custom-functions.html
- HyperFormula named expressions: https://hyperformula.handsontable.com/docs/guide/cell-references.html#relative-references
- HyperFormula license key: https://hyperformula.handsontable.com/docs/guide/license-key.html
## Navigation
- Keyboard shortcuts: https://handsontable.com/docs/react-data-grid/keyboard-shortcuts/
- Custom shortcuts: https://handsontable.com/docs/react-data-grid/custom-shortcuts/
- Focus scopes: https://handsontable.com/docs/react-data-grid/focus-scopes/
- Searching values: https://handsontable.com/docs/react-data-grid/searching-values/
## Accessibility
- Accessibility guide: https://handsontable.com/docs/react-data-grid/accessibility/
## Menus & Accessories
- Context menu: https://handsontable.com/docs/react-data-grid/context-menu/
- Undo and redo: https://handsontable.com/docs/react-data-grid/undo-redo/
- Icon pack: https://handsontable.com/docs/react-data-grid/icon-pack/
- Export to CSV: https://handsontable.com/docs/react-data-grid/export-to-csv/
- Export to Excel/XLSX (v17.1+): https://handsontable.com/docs/react-data-grid/export-to-excel/
- Notification (v17.1+): https://handsontable.com/docs/react-data-grid/notification/
- Empty data state: https://handsontable.com/docs/react-data-grid/empty-data-state/
## Dialog & Loading
- Dialog: https://handsontable.com/docs/react-data-grid/dialog/
- Loading indicator: https://handsontable.com/docs/react-data-grid/loading/
## Internationalization
- Language: https://handsontable.com/docs/react-data-grid/language/
- Locale: https://handsontable.com/docs/react-data-grid/locale/
- Layout direction (RTL/LTR): https://handsontable.com/docs/react-data-grid/layout-direction/
- IME support: https://handsontable.com/docs/react-data-grid/ime-support/
## Tools & Building
- Modules (tree-shaking): https://handsontable.com/docs/react-data-grid/modules/
- Custom plugins: https://handsontable.com/docs/react-data-grid/custom-plugins/
- Custom builds: https://handsontable.com/docs/react-data-grid/custom-builds/
- Testing: https://handsontable.com/docs/react-data-grid/testing/
## Optimization
- Batch operations: https://handsontable.com/docs/react-data-grid/batch-operations/
- Performance: https://handsontable.com/docs/react-data-grid/performance/
- Bundle size: https://handsontable.com/docs/react-data-grid/bundle-size/
## Security
- Security guide: https://handsontable.com/docs/react-data-grid/security/
## API Reference
- API overview: https://handsontable.com/docs/react-data-grid/api/
- Core (instance methods): https://handsontable.com/docs/react-data-grid/api/core/
- Hooks (all events): https://handsontable.com/docs/react-data-grid/api/hooks/
- Configuration options (all props): https://handsontable.com/docs/react-data-grid/api/options/
- Plugins index: https://handsontable.com/docs/react-data-grid/api/plugins/
### Individual Plugin APIs
- AutoColumnSize: https://handsontable.com/docs/react-data-grid/api/auto-column-size/
- AutoRowSize: https://handsontable.com/docs/react-data-grid/api/auto-row-size/
- Autofill: https://handsontable.com/docs/react-data-grid/api/autofill/
- BindRowsWithHeaders: https://handsontable.com/docs/react-data-grid/api/bind-rows-with-headers/
- CollapsibleColumns: https://handsontable.com/docs/react-data-grid/api/collapsible-columns/
- ColumnSorting: https://handsontable.com/docs/react-data-grid/api/column-sorting/
- ColumnSummary: https://handsontable.com/docs/react-data-grid/api/column-summary/
- Comments: https://handsontable.com/docs/react-data-grid/api/comments/
- ContextMenu: https://handsontable.com/docs/react-data-grid/api/context-menu/
- CopyPaste: https://handsontable.com/docs/react-data-grid/api/copy-paste/
- CustomBorders: https://handsontable.com/docs/react-data-grid/api/custom-borders/
- DataProvider (v17.1+): https://handsontable.com/docs/react-data-grid/api/data-provider/
- Dialog: https://handsontable.com/docs/react-data-grid/api/dialog/
- DragToScroll: https://handsontable.com/docs/react-data-grid/api/drag-to-scroll/
- DropdownMenu: https://handsontable.com/docs/react-data-grid/api/dropdown-menu/
- EmptyDataState: https://handsontable.com/docs/react-data-grid/api/empty-data-state/
- ExportFile: https://handsontable.com/docs/react-data-grid/api/export-file/
- Filters: https://handsontable.com/docs/react-data-grid/api/filters/
- Formulas: https://handsontable.com/docs/react-data-grid/api/formulas/
- HiddenColumns: https://handsontable.com/docs/react-data-grid/api/hidden-columns/
- HiddenRows: https://handsontable.com/docs/react-data-grid/api/hidden-rows/
- Loading: https://handsontable.com/docs/react-data-grid/api/loading/
- ManualColumnFreeze: https://handsontable.com/docs/react-data-grid/api/manual-column-freeze/
- ManualColumnMove: https://handsontable.com/docs/react-data-grid/api/manual-column-move/
- ManualColumnResize: https://handsontable.com/docs/react-data-grid/api/manual-column-resize/
- ManualRowMove: https://handsontable.com/docs/react-data-grid/api/manual-row-move/
- ManualRowResize: https://handsontable.com/docs/react-data-grid/api/manual-row-resize/
- MergeCells: https://handsontable.com/docs/react-data-grid/api/merge-cells/
- MultiColumnSorting: https://handsontable.com/docs/react-data-grid/api/multi-column-sorting/
- NestedHeaders: https://handsontable.com/docs/react-data-grid/api/nested-headers/
- NestedRows: https://handsontable.com/docs/react-data-grid/api/nested-rows/
- Notification (v17.1+): https://handsontable.com/docs/react-data-grid/api/notification/
- Pagination: https://handsontable.com/docs/react-data-grid/api/pagination/
- Search: https://handsontable.com/docs/react-data-grid/api/search/
- StretchColumns: https://handsontable.com/docs/react-data-grid/api/stretch-columns/
- TrimRows: https://handsontable.com/docs/react-data-grid/api/trim-rows/
- UndoRedo: https://handsontable.com/docs/react-data-grid/api/undo-redo/
## Recipes (new in v17)
- Recipes index: https://handsontable.com/docs/react-data-grid/recipes/
- Load data from a REST API (DataProvider, v17.1+): https://handsontable.com/docs/react-data-grid/recipes/data-management/load-data-rest-api/
## Upgrade & Migration
- Changelog: https://handsontable.com/docs/react-data-grid/changelog/
- Versioning policy: https://handsontable.com/docs/react-data-grid/versioning-policy/
- Deprecation policy: https://handsontable.com/docs/react-data-grid/deprecation-policy/
- Long Term Support (LTS): https://handsontable.com/docs/react-data-grid/long-term-support/
- 16.2 → 17.0 migration: https://handsontable.com/docs/react-data-grid/migration-from-16.2-to-17.0/
- 16.0 → 16.1 migration: https://handsontable.com/docs/react-data-grid/migration-from-16.0-to-16.1/
- 15.3 → 16.0 migration: https://handsontable.com/docs/react-data-grid/migration-from-15.3-to-16.0/
- 14.6 → 15.0 migration: https://handsontable.com/docs/react-data-grid/migration-from-14.6-to-15.0/
## Other Framework Installation
- JavaScript: https://handsontable.com/docs/javascript-data-grid/installation/
- Angular: https://handsontable.com/docs/angular-data-grid/installation/
- Vue 3: https://handsontable.com/docs/react-data-grid/vue3-installation/
## SSR Examples (CodeSandbox)
- Next.js: https://codesandbox.io/p/sandbox/kwnjph?file=https://handsontable.com/codesandbox-vm?example-dir=next.js&handsontable-version=17.1preview=true
- Astro: https://codesandbox.io/p/sandbox/gnqcwn?file=https://handsontable.com/codesandbox-vm?example-dir=astro&handsontable-version=17.1preview=true
- Remix: https://codesandbox.io/p/sandbox/njcjlq?file=https://handsontable.com/codesandbox-vm?example-dir=remix&handsontable-version=17.1preview=true
- Nuxt: https://codesandbox.io/p/sandbox/r7qsjc?file=https://handsontable.com/codesandbox-vm?example-dir=nuxt&handsontable-version=17.1preview=true
## CDN Links (jsDelivr) — latest
- JS (full bundle): https://cdn.jsdelivr.net/npm/handsontable/dist/handsontable.full.min.js
- Base CSS: https://cdn.jsdelivr.net/npm/handsontable/styles/handsontable.min.css
- Theme Main: https://cdn.jsdelivr.net/npm/handsontable/styles/ht-theme-main.min.css
- Theme Horizon: https://cdn.jsdelivr.net/npm/handsontable/styles/ht-theme-horizon.min.css
- Theme Classic: https://cdn.jsdelivr.net/npm/handsontable/styles/ht-theme-classic.min.css
- React wrapper: https://cdn.jsdelivr.net/npm/@handsontable/react-wrapper/dist/react-handsontable.min.js
- HyperFormula: https://cdn.jsdelivr.net/npm/hyperformula/dist/hyperformula.full.min.js
Pin versions by adding `@17.1` after the package name (e.g., `handsontable@17.1`).
## Package Registries
- npm: https://www.npmjs.com/package/handsontable
- NuGet: https://www.nuget.org/packages/handsontable
## Community & Support
- Developer Forum: https://forum.handsontable.com/
- GitHub Issues: https://github.com/handsontable/handsontable/issues
- Stack Overflow: https://stackoverflow.com/tags/handsontable
- Commercial support: support@handsontable.com
- Contact form: https://handsontable.com/contact
- Blog / Release Notes: https://handsontable.com/blog/categories/release-notes
- Download page: https://handsontable.com/download
+85
View File
@@ -0,0 +1,85 @@
# @handsontable/hyperformula-skill
An agent skill for [**HyperFormula**](https://hyperformula.handsontable.com) — the headless, open-source TypeScript spreadsheet calculation engine. It gives any AI coding agent deep, task-oriented knowledge of HyperFormula so the agent can help you integrate, configure, and debug the engine faster.
This package is the npm distribution of the `hyperformula` skill maintained in [`handsontable/handsontable-skills`](https://github.com/handsontable/handsontable-skills). The package version tracks the HyperFormula product version the skill targets (e.g. `3.3.0` targets HyperFormula 3.3.0).
## What's in the package
A self-contained skill — plain markdown, no runtime dependencies:
```
SKILL.md ← entry point: concepts, routing, and a docs map (YAML frontmatter + body)
references/ ← task-oriented deep-dives the agent reads on demand
```
`SKILL.md` follows the [Agent Skills](https://claude.com/blog/skills) layout (a YAML frontmatter block with `name`/`description`, followed by markdown instructions). Any agent that can load a skill — or simply read a folder of markdown instructions — can use it.
## Install
```bash
npm install @handsontable/hyperformula-skill
```
The installed package lives at `node_modules/@handsontable/hyperformula-skill`. Resolve that path programmatically with:
```bash
node -p "require.resolve('@handsontable/hyperformula-skill/SKILL.md')"
```
Then make the skill available to your agent using whichever of the following matches it:
### Claude Code
Copy the package into a skills directory. User scope (available in every project):
```bash
cp -r node_modules/@handsontable/hyperformula-skill ~/.claude/skills/hyperformula
```
Or project scope, from your project root:
```bash
cp -r node_modules/@handsontable/hyperformula-skill .claude/skills/hyperformula
```
### Claude API
Upload the package contents (`SKILL.md` + `references/`) to the [Skills API](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview).
### OpenAI Codex
Codex discovers [skills](https://developers.openai.com/codex/skills) as folders containing a `SKILL.md`, under `~/.agents/skills` (available in every repo) or `.agents/skills` in a repo (checked in for your team). Copy the package into one of those locations:
```bash
# User scope — available in every repo
cp -r node_modules/@handsontable/hyperformula-skill ~/.agents/skills/hyperformula
# Repo scope — from your project root
cp -r node_modules/@handsontable/hyperformula-skill .agents/skills/hyperformula
```
Codex also follows symlinked skill folders, so you can instead link the installed package and let `npm install` keep it current:
```bash
ln -s "$PWD/node_modules/@handsontable/hyperformula-skill" ~/.agents/skills/hyperformula
```
### Any other agent
Most coding agents support a skills, rules, or knowledge directory. Copy (or symlink) the package folder into it, for example:
```bash
# Replace <agent-skills-dir> with your agent's skills/knowledge directory
cp -r node_modules/@handsontable/hyperformula-skill <agent-skills-dir>/hyperformula
```
If your agent reads a single instruction file rather than a folder, point it at `SKILL.md`; it links the files under `references/` so the agent can pull them in as needed. For RAG / vector-store setups, ingest `SKILL.md` together with every file under `references/` (the repository also publishes a pre-flattened `hyperformula-rag.md` for this case).
## Other distribution formats
The same skill source is also shipped as a drag-and-drop `.zip` (Cowork / Claude.ai web), a flattened `-rag.md` doc (RAG / vector stores), and a Claude Code plugin marketplace entry. See the [repository README](https://github.com/handsontable/handsontable-skills#readme) for details.
## License
MIT — see the [repository](https://github.com/handsontable/handsontable-skills/blob/main/LICENSE.txt). HyperFormula itself is separately licensed (GPLv3 or commercial); see the [licensing guide](https://hyperformula.handsontable.com/docs/guide/licensing.html).
+134
View File
@@ -0,0 +1,134 @@
---
name: hyperformula
description: >
Use this skill when the user works with HyperFormula (HF) — a headless,
open-source TypeScript spreadsheet calculation engine. Use it when the user:
mentions HyperFormula or HF; wants to integrate Excel-like formulas into a
JS/TS app; evaluate formulas programmatically in a browser or Node.js;
simulate spreadsheet or Excel calculation behavior server-side; run
calculations over data parsed from XLSX files (e.g. via SheetJS) in code;
build a pricing engine, financial model, or what-if analysis in code; define
custom spreadsheet functions or named expressions outside of a UI context. Do
NOT use this skill for: general Excel questions unrelated to HF; general
Google Sheets questions; generic spreadsheet formula-syntax questions outside
an HF context; formulas used inside Handsontable (use the "handsontable"
skill instead).
---
# HyperFormula
HyperFormula is a **headless, open-source TypeScript spreadsheet calculation engine** for embedding spreadsheet logic in any JavaScript/TypeScript application (browser or Node.js). ~420 built-in functions, dependency graph, undo/redo, i18n (17 languages). Dual-licensed: GPLv3 or commercial.
- Docs: https://hyperformula.handsontable.com/
- npm: https://www.npmjs.com/package/hyperformula
- GitHub: https://github.com/handsontable/hyperformula
## Where to go next
Task-oriented references in `references/` (open the one that matches what the user is doing):
- [`getting-started.md`](references/getting-started.md) — how to install, create an instance (`buildFromArray` / `buildFromSheets` / `buildEmpty`), and work with cell addresses. Open this for onboarding questions and first-run errors.
- [`api-quickref.md`](references/api-quickref.md) — runnable examples for CRUD, rows/columns, sheets, exporting data, batching, named expressions, events, undo/redo, clipboard. Open this when implementing or debugging HF API calls.
- [`custom-functions.md`](references/custom-functions.md) — extending HyperFormula via `FunctionPlugin`: minimal plugin, argument types, volatile functions, range arguments, returning arrays, error handling, aliases, localized names. Open this when adding or debugging custom spreadsheet functions.
- [`configuration.md`](references/configuration.md) — `ConfigParams` options, Excel-compatibility preset, Google-Sheets preset, and config-related pitfalls (separator collisions, Node ICU, `precisionRounding` change in v3). Open this when tuning behavior or diagnosing locale issues.
- [`vue3.md`](references/vue3.md) — Vue 3 integration: `markRaw` requirement, Composition API, Pinia/Vuex stores, `destroy()` on unmount. Open this when embedding HF in a Vue 3 app.
- [`error-handling.md`](references/error-handling.md) — inspecting `CellError`, `ErrorType` enum, `getCellValueDetailedType`, common error causes (`#NAME?`, `#CYCLE!`, `#REF!`, …). Open this when a cell returns an error or you need to branch on result type.
- [`general-pitfalls.md`](references/general-pitfalls.md) — cross-cutting gotchas: `destroy()` lifecycle, forcing literal strings, Excel-parity caveats, hard limits. Open this when results look wrong or memory grows unboundedly.
Below this section is the **Documentation map** — the canonical directory of links to the official HyperFormula docs. Use it when pointing the user to authoritative material.
## Documentation map
All links resolve to `hyperformula.handsontable.com` unless noted.
### Introduction
- Welcome / Homepage: https://hyperformula.handsontable.com/
- Demo: https://hyperformula.handsontable.com/docs/guide/demo.html
### Overview
- Quality (test coverage, CI): https://hyperformula.handsontable.com/docs/guide/quality.html
- Supported browsers: https://hyperformula.handsontable.com/docs/guide/supported-browsers.html
- Dependencies: https://hyperformula.handsontable.com/docs/guide/dependencies.html
- Licensing (GPLv3 vs commercial): https://hyperformula.handsontable.com/docs/guide/licensing.html
- Support: https://hyperformula.handsontable.com/docs/guide/support.html
### Getting Started
- Client-side installation: https://hyperformula.handsontable.com/docs/guide/client-side-installation.html
- Server-side installation (Node.js): https://hyperformula.handsontable.com/docs/guide/server-side-installation.html
- Basic usage: https://hyperformula.handsontable.com/docs/guide/basic-usage.html
- Advanced usage: https://hyperformula.handsontable.com/docs/guide/advanced-usage.html
- Configuration options guide: https://hyperformula.handsontable.com/docs/guide/configuration-options.html
- License key setup: https://hyperformula.handsontable.com/docs/guide/license-key.html
### Framework Integration
- React: https://hyperformula.handsontable.com/docs/guide/integration-with-react.html
- Vue: https://hyperformula.handsontable.com/docs/guide/integration-with-vue.html
- Angular: https://hyperformula.handsontable.com/docs/guide/integration-with-angular.html
- Svelte: https://hyperformula.handsontable.com/docs/guide/integration-with-svelte.html
### Data Operations
- Basic operations (CRUD): https://hyperformula.handsontable.com/docs/guide/basic-operations.html
- Batch operations: https://hyperformula.handsontable.com/docs/guide/batch-operations.html
- Clipboard operations: https://hyperformula.handsontable.com/docs/guide/clipboard-operations.html
- Undo-redo: https://hyperformula.handsontable.com/docs/guide/undo-redo.html
- Sorting data: https://hyperformula.handsontable.com/docs/guide/sorting-data.html
### Formulas
- Specifications and limits: https://hyperformula.handsontable.com/docs/guide/specifications-and-limits.html
- Cell references (relative, absolute, mixed, cross-sheet): https://hyperformula.handsontable.com/docs/guide/cell-references.html
- Types of values: https://hyperformula.handsontable.com/docs/guide/types-of-values.html
- Types of errors: https://hyperformula.handsontable.com/docs/guide/types-of-errors.html
- Types of operators: https://hyperformula.handsontable.com/docs/guide/types-of-operators.html
- Order of precedence: https://hyperformula.handsontable.com/docs/guide/order-of-precendece.html
- Built-in functions (full list, ~400): https://hyperformula.handsontable.com/docs/guide/built-in-functions.html
- Volatile functions: https://hyperformula.handsontable.com/docs/guide/volatile-functions.html
- Named expressions: https://hyperformula.handsontable.com/docs/guide/named-expressions.html
- Array formulas / ARRAYFORMULA: https://hyperformula.handsontable.com/docs/guide/arrays.html
### Internationalization
- i18n features (17 languages): https://hyperformula.handsontable.com/docs/guide/i18n-features.html
- Localizing function names: https://hyperformula.handsontable.com/docs/guide/localizing-functions.html
- Date and time handling: https://hyperformula.handsontable.com/docs/guide/date-and-time-handling.html
### Compatibility
- Microsoft Excel compatibility: https://hyperformula.handsontable.com/docs/guide/compatibility-with-microsoft-excel.html
- Google Sheets compatibility: https://hyperformula.handsontable.com/docs/guide/compatibility-with-google-sheets.html
- Runtime differences (Excel & Sheets): https://hyperformula.handsontable.com/docs/guide/list-of-differences.html
### Advanced Topics
- Key concepts (AST, dependency graph, evaluation): https://hyperformula.handsontable.com/docs/guide/key-concepts.html
- Dependency graph: https://hyperformula.handsontable.com/docs/guide/dependency-graph.html
- Building & testing from source: https://hyperformula.handsontable.com/docs/guide/building.html
- Custom functions (FunctionPlugin): https://hyperformula.handsontable.com/docs/guide/custom-functions.html
- Performance: https://hyperformula.handsontable.com/docs/guide/performance.html
- Known limitations: https://hyperformula.handsontable.com/docs/guide/known-limitations.html
- File import: https://hyperformula.handsontable.com/docs/guide/file-import.html
### Upgrade & Migration
- Release notes / Changelog: https://hyperformula.handsontable.com/docs/guide/release-notes.html
- 0.6 → 1.0 migration: https://hyperformula.handsontable.com/docs/guide/migration-from-0.6-to-1.0.html
- 1.x → 2.0 migration: https://hyperformula.handsontable.com/docs/guide/migration-from-1.x-to-2.0.html
- 2.x → 3.0 migration: https://hyperformula.handsontable.com/docs/guide/migration-from-2.x-to-3.0.html
### API Reference
- API overview: https://hyperformula.handsontable.com/docs/api/
- HyperFormula class (all methods): https://hyperformula.handsontable.com/docs/api/classes/hyperformula.html
- ConfigParams interface (all options): https://hyperformula.handsontable.com/docs/api/interfaces/configparams.html
- Listeners interface (all events): https://hyperformula.handsontable.com/docs/api/interfaces/listeners.html
### npm
- npm page: https://www.npmjs.com/package/hyperformula
### Community & Support
- GitHub repo: https://github.com/handsontable/hyperformula
- GitHub Issues: https://github.com/handsontable/hyperformula/issues
- GitHub Discussions: https://github.com/handsontable/hyperformula/discussions
- Developer Forum: https://forum.handsontable.com/
- Commercial support: support@handsontable.com
- Sales (commercial license): sales@handsontable.com
- Contact form: https://handsontable.com/contact
---
> **Last updated: 2026-05-20 · Aligned with HyperFormula 3.3.0.**
> If the user is on a newer release, confirm API shape against the latest docs (see the **Release notes** link above) before relying on this file.
+34
View File
@@ -0,0 +1,34 @@
{
"name": "@handsontable/hyperformula-skill",
"version": "3.3.0",
"description": "Agent skill for HyperFormula — the headless, open-source TypeScript spreadsheet calculation engine. Teaches AI coding agents how to integrate, configure, and debug HyperFormula.",
"license": "MIT",
"author": "Handsontable <hello@handsontable.com> (https://handsontable.com)",
"homepage": "https://github.com/handsontable/handsontable-skills#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/handsontable/handsontable-skills.git",
"directory": "skills/hyperformula"
},
"bugs": {
"url": "https://github.com/handsontable/handsontable-skills/issues"
},
"keywords": [
"agent-skill",
"claude-skill",
"claude",
"anthropic",
"ai",
"hyperformula",
"spreadsheet",
"formula-engine",
"handsontable"
],
"files": [
"SKILL.md",
"references/"
],
"publishConfig": {
"access": "public"
}
}
@@ -0,0 +1,147 @@
# API Quick Reference
Runnable examples for the most-used HyperFormula APIs. Authoritative docs:
- Basic operations: https://hyperformula.handsontable.com/docs/guide/basic-operations.html
- Batch operations: https://hyperformula.handsontable.com/docs/guide/batch-operations.html
- Named expressions: https://hyperformula.handsontable.com/docs/guide/named-expressions.html
- Clipboard operations: https://hyperformula.handsontable.com/docs/guide/clipboard-operations.html
- Undo-redo: https://hyperformula.handsontable.com/docs/guide/undo-redo.html
- Sorting data: https://hyperformula.handsontable.com/docs/guide/sorting-data.html
- HyperFormula class (all methods): https://hyperformula.handsontable.com/docs/api/classes/hyperformula.html
- Listeners (all events): https://hyperformula.handsontable.com/docs/api/interfaces/listeners.html
## CRUD
```ts
// Write: string, number, or formula
hf.setCellContents({ sheet: 0, col: 0, row: 0 }, 'Hello');
hf.setCellContents({ sheet: 0, col: 1, row: 0 }, '=A1 & " World"');
// Read
hf.getCellValue({ sheet: 0, col: 1, row: 0 }); // computed result
hf.getCellFormula({ sheet: 0, col: 1, row: 0 }); // '=A1 & " World"'
hf.getCellType({ sheet: 0, col: 0, row: 0 }); // CellType.FORMULA | VALUE | EMPTY
```
## Rows and columns
Second arg is `[startIndex, count]`, not a list of indexes.
```ts
hf.addRows(sheetId, [rowIndex, numberOfRows]);
hf.removeRows(sheetId, [rowIndex, numberOfRows]);
hf.addColumns(sheetId, [colIndex, numberOfColumns]);
hf.removeColumns(sheetId, [colIndex, numberOfColumns]);
```
## Sheets
```ts
hf.addSheet('NewSheet');
hf.removeSheet(sheetId);
hf.renameSheet(sheetId, 'BetterName');
hf.countSheets();
hf.getSheetName(sheetId);
hf.getSheetId('SheetName');
hf.getSheetDimensions(sheetId); // → { width, height }
```
## Export data
```ts
hf.getSheetValues(sheetId); // computed values as 2D array
hf.getSheetSerialized(sheetId); // formulas/raw values as 2D array
hf.getAllSheetsValues(); // { SheetName: values[][] }
hf.getAllSheetsSerialized(); // { SheetName: formulas[][] }
```
## Batch operations
Every `setCellContents` call triggers a full dependency-graph recalculation. Always batch when writing more than one cell.
```ts
// Preferred: batch() — returns ExportedChange[]
const changes = hf.batch(() => {
hf.setCellContents({ sheet: 0, col: 0, row: 0 }, '100');
hf.setCellContents({ sheet: 0, col: 0, row: 1 }, '200');
hf.addRows(0, [2, 1]);
});
// `changes` contains all cells that were recalculated.
// For bulk imports (value writes only):
hf.suspendEvaluation();
// ... hundreds of setCellContents calls ...
hf.resumeEvaluation(); // single recalc
// PITFALL: structural ops (addRows/moveRows/...) during suspendEvaluation
// have degraded performance. Use batch() when mixing structural + value writes.
```
## Sorting
`setRowOrder` takes a **permutation array**, not a comparator. Compute the new index sequence externally, then pass it in.
```ts
// Sort rows by the value in column 0
const rowCount = hf.getSheetDimensions(0).height;
const indexes = Array.from({ length: rowCount }, (_, i) => i);
indexes.sort((a, b) => {
const va = hf.getCellValue({ sheet: 0, col: 0, row: a }) as number;
const vb = hf.getCellValue({ sheet: 0, col: 0, row: b }) as number;
return va - vb;
});
hf.setRowOrder(0, indexes); // e.g. [2, 0, 1, 3]
```
## Named expressions
Reusable names for values or formulas. Can be global or scoped to a sheet (local shadows global).
```ts
hf.addNamedExpression('TAX_RATE', '0.21');
hf.addNamedExpression('TOTAL_REVENUE', '=SUM(Revenue!A:A)');
hf.setCellContents({ sheet: 0, col: 0, row: 0 }, '=1000 * TAX_RATE');
hf.listNamedExpressions(); // all registered names
```
## Custom functions
See [custom-functions.md](custom-functions.md) — `FunctionPlugin`, argument types, volatile functions, range arguments, returning arrays, error handling, aliases, localized names.
## Events
Subscribe via `.on()` on the instance. Full list: https://hyperformula.handsontable.com/docs/api/interfaces/listeners.html
```ts
hf.on('valuesUpdated', (changes) => {
changes.forEach((c) => console.log(c.address, c.newValue));
});
hf.on('sheetAdded', (addedSheetName) => { /* ... */ });
hf.on('sheetRemoved', (removedSheetName, removedSheetData) => { /* ... */ });
hf.on('sheetRenamed', (oldName, newName) => { /* ... */ });
```
## Undo / redo
```ts
hf.undo();
hf.redo();
hf.isThereSomethingToUndo();
hf.isThereSomethingToRedo();
hf.clearUndoStack();
```
Configure depth via `undoLimit` in `ConfigParams` (see [configuration.md](configuration.md)).
## Clipboard
```ts
hf.copy({ start: { sheet: 0, col: 0, row: 0 }, end: { sheet: 0, col: 1, row: 1 } });
hf.cut ({ start: { sheet: 0, col: 0, row: 0 }, end: { sheet: 0, col: 1, row: 1 } });
hf.paste({ sheet: 0, col: 5, row: 5 });
hf.isClipboardEmpty();
hf.clearClipboard();
```
@@ -0,0 +1,92 @@
# Configuration
`ConfigParams` + compatibility presets + config-specific pitfalls. Authoritative docs:
- Configuration options guide: https://hyperformula.handsontable.com/docs/guide/configuration-options.html
- ConfigParams (all options): https://hyperformula.handsontable.com/docs/api/interfaces/configparams.html
- Excel compatibility: https://hyperformula.handsontable.com/docs/guide/compatibility-with-microsoft-excel.html
- Google Sheets compatibility: https://hyperformula.handsontable.com/docs/guide/compatibility-with-google-sheets.html
## ConfigParams highlights
Pass as the second argument to any factory method.
```ts
const hf = HyperFormula.buildEmpty({
licenseKey: 'gpl-v3', // required — 'gpl-v3' for open source
precisionRounding: 10, // decimal rounding precision (default 10; was 14 before v3)
functionArgSeparator: ',', // separator between function arguments
dateFormats: ['DD/MM/YYYY', 'DD-MM-YYYY'],
nullDate: { year: 1900, month: 1, day: 1 },
leapYear1900: false, // Excel bug compat: treat 1900 as leap year
maxRows: 40000, // max rows per sheet (default 40000)
maxColumns: 18278, // max columns per sheet (default 18278 = 'ZZZ')
undoLimit: 20, // undo history depth
maxPendingLazyTransformations: 1000, // v3.3+ — cap accumulated lazy transformations before cleanup
});
```
## Excel compatibility preset
```ts
const hf = HyperFormula.buildEmpty({
licenseKey: 'gpl-v3',
useArrayArithmetic: true,
useWildcards: true,
evaluateNullToZero: true,
leapYear1900: true, // Excel's intentional 1900 leap-year bug
ignoreWhiteSpace: 'any',
caseSensitive: false,
accentSensitive: true,
});
```
## Google Sheets compatibility preset
Defaults already match Google Sheets behavior (`leapYear1900: false`, `useArrayArithmetic: false`).
```ts
const hf = HyperFormula.buildEmpty({ licenseKey: 'gpl-v3' });
```
## Config-specific pitfalls
### Vue 3
Vue 3 requires wrapping the instance with `markRaw` — see [vue3.md](vue3.md) for the full integration guide (React / Angular / Svelte need no special handling).
### `functionArgSeparator` vs `thousandSeparator` collision
These two options **cannot share a character**. European locales that use `,` as thousand separator must change the argument separator:
```ts
const hf = HyperFormula.buildEmpty({
licenseKey: 'gpl-v3',
thousandSeparator: ',',
decimalSeparator: '.',
functionArgSeparator: ';', // must differ from thousandSeparator
});
```
### Node.js must have full ICU
String comparisons (used in `MATCH`, `VLOOKUP`, sorting) can silently produce wrong results on Node.js < 13 or builds without full ICU. Verify at startup:
```ts
// Must report 'full' (or a detailed ICU version), not 'small'.
console.log(process.versions.icu);
```
### Tuning `maxPendingLazyTransformations` (v3.3+)
HyperFormula defers some structural transformations (row/column insertions, moves) and applies them lazily. In long-lived instances with heavy mutation throughput — bulk imports, frequent undo/redo, scripted batch edits — the pending queue can grow before cleanup. v3.3 fixed the unbounded-growth leak; this option lets you cap the queue explicitly. Lower values trade memory for more frequent flush work; the default is suitable for typical UI workloads.
### `precisionRounding` default changed in v3
Before v3 the default was `14`. It is now `10`. Calculations relying on the old precision need an explicit override:
```ts
const hf = HyperFormula.buildEmpty({
licenseKey: 'gpl-v3',
precisionRounding: 14, // pre-v3 behavior
});
```
@@ -0,0 +1,174 @@
# Custom Functions
Extend HyperFormula with your own functions via `FunctionPlugin`. Authoritative doc:
- Custom functions guide: https://hyperformula.handsontable.com/docs/guide/custom-functions.html
## Minimal plugin
Register **before** creating any instance — functions registered after `buildFromArray` / `buildFromSheets` / `buildEmpty` won't be available.
```ts
import { HyperFormula, FunctionPlugin, FunctionArgumentType } from 'hyperformula';
class MyPlugin extends FunctionPlugin {
greet(ast, state) {
return this.runFunction(
ast.args,
state,
this.metadata('GREET'),
(name) => `Hello, ${name}!`
);
}
}
MyPlugin.implementedFunctions = {
GREET: {
method: 'greet',
parameters: [{ argumentType: FunctionArgumentType.STRING }],
},
};
const translations = { enGB: { GREET: 'GREET' }, enUS: { GREET: 'GREET' } };
// PITFALL: registration MUST happen before any instance is built.
HyperFormula.registerFunctionPlugin(MyPlugin, translations);
const hf = HyperFormula.buildFromArray(
[['World', '=GREET(A1)']],
{ licenseKey: 'gpl-v3' }
);
console.log(hf.getCellValue({ sheet: 0, col: 1, row: 0 })); // "Hello, World!"
```
## Volatile functions
Mark a function as volatile so it recalculates on every change (like `RAND` or `NOW`). Volatile functions are expensive in large sheets — use sparingly.
```ts
MyPlugin.implementedFunctions = {
RAND_ID: {
method: 'randId',
parameters: [],
isVolatile: true,
},
};
```
## Argument types
```ts
import { FunctionArgumentType } from 'hyperformula';
// FunctionArgumentType.NUMBER
// FunctionArgumentType.STRING
// FunctionArgumentType.BOOLEAN
// FunctionArgumentType.NOERROR
// FunctionArgumentType.SCALAR
// FunctionArgumentType.RANGE // accepts a cell range
// FunctionArgumentType.ANY
```
Use `optionalArg: true`, `defaultValue`, and `minValue` / `maxValue` to validate arguments declaratively:
```ts
MyPlugin.implementedFunctions = {
CLAMP: {
method: 'clamp',
parameters: [
{ argumentType: FunctionArgumentType.NUMBER },
{ argumentType: FunctionArgumentType.NUMBER, optionalArg: true, defaultValue: 0 },
{ argumentType: FunctionArgumentType.NUMBER, optionalArg: true, defaultValue: 100 },
],
},
};
```
## Range arguments
Use `RANGE` argument type when the function takes a cell area. The callback receives the range as a 2D array.
```ts
class SumPositivesPlugin extends FunctionPlugin {
sumPositives(ast, state) {
return this.runFunction(
ast.args,
state,
this.metadata('SUM_POSITIVES'),
(range) => {
let total = 0;
for (const row of range.data) {
for (const v of row) if (typeof v === 'number' && v > 0) total += v;
}
return total;
}
);
}
}
SumPositivesPlugin.implementedFunctions = {
SUM_POSITIVES: {
method: 'sumPositives',
parameters: [{ argumentType: FunctionArgumentType.RANGE }],
},
};
```
## Returning arrays
Custom functions can return 2D arrays. **PITFALL:** result arrays don't auto-resize when upstream dependencies change — the footprint is fixed at first evaluation.
```ts
class SplitPlugin extends FunctionPlugin {
splitToRow(ast, state) {
return this.runFunction(
ast.args,
state,
this.metadata('SPLIT_ROW'),
(text, sep) => [text.split(sep)] // 2D array: one row, N cols
);
}
}
```
## Error handling
Return a `CellError` to signal a formula error:
```ts
import { CellError, ErrorType } from 'hyperformula';
class DividePlugin extends FunctionPlugin {
safeDivide(ast, state) {
return this.runFunction(
ast.args,
state,
this.metadata('SAFE_DIVIDE'),
(a, b) => (b === 0 ? new CellError(ErrorType.DIV_BY_ZERO) : a / b)
);
}
}
```
## Aliases and localized names
Expose one method under multiple function names, or localize:
```ts
MyPlugin.aliases = {
HELLO: 'GREET', // calling =HELLO(x) runs the greet() method
};
const translations = {
enGB: { GREET: 'GREET' },
plPL: { GREET: 'POWITAJ' }, // =POWITAJ("Świat") in Polish
};
HyperFormula.registerFunctionPlugin(MyPlugin, translations);
```
## Unregister / introspect
```ts
HyperFormula.unregisterFunctionPlugin(MyPlugin);
HyperFormula.unregisterFunction('GREET');
HyperFormula.getRegisteredFunctionNames('enGB');
```
@@ -0,0 +1,69 @@
# Error Handling
Inspect cell values that may be errors, tell error types apart, and check value shape. Authoritative docs:
- Types of errors: https://hyperformula.handsontable.com/docs/guide/types-of-errors.html
- Types of values: https://hyperformula.handsontable.com/docs/guide/types-of-values.html
## Always check `CellError` before using a result
Cell values can be errors (`#DIV/0!`, `#VALUE!`, `#REF!`, etc.). Always test before using a result.
```ts
import { CellError, ErrorType } from 'hyperformula';
const value = hf.getCellValue({ sheet: 0, col: 0, row: 0 });
if (value instanceof CellError) {
// ErrorType enum: DIV_BY_ZERO, VALUE, REF, NAME, NUM, NA, CYCLE, ERROR
switch (value.type) {
case ErrorType.CYCLE:
console.log('Circular reference');
break;
case ErrorType.NAME:
// Usually: function not registered (check plugin registration or i18n language)
console.log('Unknown name:', value.message);
break;
default:
console.log('Error:', value.type, value.message);
}
} else {
console.log('Value:', value);
}
```
## `#CYCLE!` is HyperFormula-specific
Standard spreadsheet apps report cycles differently. HyperFormula's `IF` also reports cycles for all branches, even unreachable ones — this can produce `#CYCLE!` in formulas that Excel or Sheets would evaluate.
## Inspect value shape without catching errors
```ts
import { CellValueDetailedType } from 'hyperformula';
hf.getCellValueDetailedType({ sheet: 0, col: 0, row: 0 });
// → CellValueDetailedType.NUMBER | STRING | BOOLEAN | ERROR | EMPTY | ...
```
Use the detailed type when you need to distinguish e.g. number vs empty without touching the value.
## Returning errors from custom functions
Custom `FunctionPlugin` methods can return a `CellError` to surface a formula error. See [custom-functions.md](custom-functions.md) for the full pattern.
```ts
import { CellError, ErrorType } from 'hyperformula';
return new CellError(ErrorType.DIV_BY_ZERO);
```
## Common causes
| Error | Common cause |
|---|---|
| `#NAME?` | Function not registered (check `registerFunctionPlugin` order or `language` config) |
| `#CYCLE!` | Circular reference — or an `IF` branch that *could* produce one |
| `#REF!` | Deleted row/column broke a formula reference |
| `#VALUE!` | Type mismatch — e.g. passing a string where a number is expected |
| `#DIV/0!` | Division by zero, including empty cells coerced to 0 |
| `#NUM!` | Out-of-range numeric result (e.g. `SQRT(-1)`) |
| `#N/A` | Lookup miss (`MATCH`, `VLOOKUP`) or propagated from an upstream `#N/A` |
@@ -0,0 +1,48 @@
# General Pitfalls
Cross-cutting gotchas that aren't tied to a specific API or config option. Authoritative docs:
- Known limitations: https://hyperformula.handsontable.com/docs/guide/known-limitations.html
- Built-in functions (full list): https://hyperformula.handsontable.com/docs/guide/built-in-functions.html
- Runtime differences vs Excel/Sheets: https://hyperformula.handsontable.com/docs/guide/list-of-differences.html
## Error handling
See [error-handling.md](error-handling.md) — checking `CellError`, `ErrorType` enum, `getCellValueDetailedType`, common error causes.
## Always call `destroy()` in long-running apps
HyperFormula maintains internal data structures (dependency graph, address mapping) that are **not** garbage-collected until `destroy()` is called. Leaking instances in servers or SPAs accumulates memory.
```ts
hf.destroy();
// After destroy() the instance is unusable — create a new one if needed.
```
v3.3 fixed two longstanding leak sources inside live instances — pending lazy transformations and undo/redo history were not being trimmed. If you maintain very long-lived instances with heavy mutation throughput, also see `maxPendingLazyTransformations` in [configuration.md](configuration.md) to bound the lazy-transformation queue. `destroy()` is still mandatory at teardown.
## Force a string that looks like a formula
Prefix with `'` (apostrophe) to store the literal text instead of evaluating.
```ts
// Stored as the literal string "=SUM(1,2)", not a formula:
hf.setCellContents({ sheet: 0, col: 0, row: 0 }, "'=SUM(1,2)");
```
## Don't assume Excel parity
~68% of Excel functions are covered. Runtime differences exist even for implemented functions. Before relying on behavior, check:
- Full built-in list: https://hyperformula.handsontable.com/docs/guide/built-in-functions.html
- Runtime differences: https://hyperformula.handsontable.com/docs/guide/list-of-differences.html
## `licenseKey` is always required
Every factory method (`buildFromArray`, `buildFromSheets`, `buildEmpty`) requires `licenseKey`. Use `'gpl-v3'` for open-source use or your commercial key.
## Known hard limits
- **Single workbook per instance** — no multi-workbook support.
- No 3D references, dynamic arrays, async functions, structured references ("Tables"), or relative named expressions.
- `IF` reports cycles for all branches, even unreachable ones.
- Custom function result arrays don't auto-resize when dependencies change.
@@ -0,0 +1,82 @@
# Getting Started
Install, create an instance, read/write cells. Authoritative docs:
- Client-side install: https://hyperformula.handsontable.com/docs/guide/client-side-installation.html
- Server-side install: https://hyperformula.handsontable.com/docs/guide/server-side-installation.html
- Basic usage: https://hyperformula.handsontable.com/docs/guide/basic-usage.html
## Install
### npm
```bash
npm install hyperformula
```
### CDN (jsDelivr, pinned version)
```html
<script src="https://cdn.jsdelivr.net/npm/hyperformula@3.2.0/dist/hyperformula.full.min.js"></script>
```
### Node.js
Same npm install. Requires Node.js 13+ with full ICU for locale-aware string comparison.
## Create an instance
Every factory method requires `licenseKey`. Use `'gpl-v3'` for open-source use or your commercial key.
### `buildFromArray` — single sheet from a 2D array
```ts
import { HyperFormula } from 'hyperformula';
const hf = HyperFormula.buildFromArray(
[
['10', '20', '=SUM(A1:B1)'],
['30', '40', '=SUM(A2:B2)'],
],
{ licenseKey: 'gpl-v3' }
);
console.log(hf.getCellValue({ sheet: 0, col: 2, row: 0 })); // 30
```
### `buildFromSheets` — multi-sheet workbook
```ts
const hf = HyperFormula.buildFromSheets(
{
Revenue: [['100', '200', '=SUM(A1:B1)']],
Expenses: [['50', '=Revenue!C1 - A1']],
},
{ licenseKey: 'gpl-v3' }
);
```
Cross-sheet references use `SheetName!CellRef` syntax.
### `buildEmpty` — start empty, add sheets later
```ts
const hf = HyperFormula.buildEmpty({ licenseKey: 'gpl-v3' });
const sheetName = hf.addSheet('Data');
const sheetId = hf.getSheetId(sheetName);
hf.setCellContents({ sheet: sheetId, col: 0, row: 0 }, [
['10', '20', '=SUM(A1:B1)'],
]);
```
## Cell addresses
All addresses use zero-indexed `{ sheet, col, row }`. Convert to/from A1 notation with built-in helpers:
```ts
hf.simpleCellAddressFromString('B3', 0);
// → { sheet: 0, col: 1, row: 2 }
hf.simpleCellAddressToString({ sheet: 0, col: 1, row: 2 }, 0);
// → 'B3'
```
@@ -0,0 +1,72 @@
# Vue 3
HyperFormula + Vue 3 integration. Authoritative doc:
- Vue integration guide: https://hyperformula.handsontable.com/docs/guide/integration-with-vue.html
## Always wrap the instance with `markRaw`
Vue 3's Composition API wraps objects in a reactive Proxy that intercepts property access and **corrupts HyperFormula's internal state**, causing silent data corruption or crashes. React, Angular, and Svelte need no special handling.
```ts
import { markRaw } from 'vue';
import { HyperFormula } from 'hyperformula';
const hf = markRaw(
HyperFormula.buildEmpty({ licenseKey: 'gpl-v3' })
);
```
Use the same wrapper no matter where the instance is held — `ref`, `reactive`, component state, a store (Pinia/Vuex), or a composable. If the raw HyperFormula instance ever reaches Vue's reactivity system, it must be marked.
## Composition API example
```ts
import { onBeforeUnmount, ref } from 'vue';
import { markRaw } from 'vue';
import { HyperFormula } from 'hyperformula';
export function useHyperFormula() {
const hf = markRaw(
HyperFormula.buildEmpty({ licenseKey: 'gpl-v3' })
);
// Free internal data structures when the component unmounts.
onBeforeUnmount(() => hf.destroy());
const result = ref<unknown>(null);
function evaluate(formula: string) {
hf.setCellContents({ sheet: 0, col: 0, row: 0 }, formula);
result.value = hf.getCellValue({ sheet: 0, col: 0, row: 0 });
}
return { evaluate, result };
}
```
## Pinia / Vuex store
```ts
import { defineStore } from 'pinia';
import { markRaw } from 'vue';
import { HyperFormula } from 'hyperformula';
export const useCalcStore = defineStore('calc', {
state: () => ({
hf: markRaw(
HyperFormula.buildEmpty({ licenseKey: 'gpl-v3' })
),
}),
});
```
## Cleanup
HyperFormula's internal graph is **not** garbage-collected until `destroy()` is called. In SPAs this accumulates memory over time.
```ts
import { onBeforeUnmount } from 'vue';
onBeforeUnmount(() => hf.destroy());
// After destroy() the instance is unusable — create a new one if needed.
```