# HyperFormula Documentation
> Full documentation corpus for LLM consumption.
> Each page below is also served as clean Markdown — append `.md` to a docs page URL.
---
## Welcome
URL: https://handsontable.com/docs/hyperformula/
# Welcome
An open-source headless spreadsheet for business web apps
--- HyperFormula is a headless spreadsheet built in TypeScript, serving as both a parser and evaluator of spreadsheet formulas. It can be integrated into your browser or utilized as a service with Node.js as your back-end technology. ## What HyperFormula can be used for? HyperFormula doesn't assume any existing user interface, making it a general-purpose library that can be used in various business applications. Here are some examples: - Deterministic compute layer for AI & LLMs - Calculated fields in CRM and ERP software - Custom spreadsheet-like app - Business logic builder - Forms and form builder - Educational app - Online calculator ## Features - [Function syntax compatible with Microsoft Excel](https://handsontable.com/docs/hyperformula/guide/compatibility-with-microsoft-excel.md) and [Google Sheets](https://handsontable.com/docs/hyperformula/guide/compatibility-with-google-sheets.md) - High-speed parsing and evaluation of spreadsheet formulas - [A library of 423 built-in functions](https://handsontable.com/docs/hyperformula/guide/built-in-functions.md) - [Support for custom functions](https://handsontable.com/docs/hyperformula/guide/custom-functions.md) - [Support for Node.js](https://handsontable.com/docs/hyperformula/guide/server-side-installation.md#install-with-npm-or-yarn) - [Support for undo/redo](https://handsontable.com/docs/hyperformula/guide/undo-redo.md) - [Support for CRUD operations](https://handsontable.com/docs/hyperformula/guide/basic-operations.md) - [Support for clipboard](https://handsontable.com/docs/hyperformula/guide/clipboard-operations.md) - [Support for named expressions](https://handsontable.com/docs/hyperformula/guide/named-expressions.md) - [Support for data sorting](https://handsontable.com/docs/hyperformula/guide/sorting-data.md) - [Support for formula localization with 18 built-in languages](https://handsontable.com/docs/hyperformula/guide/i18n-features.md) - Easy integration with any front-end or back-end application - GPLv3 or a [commercial license](https://handsontable.com/get-a-quote) - Maintained by the team that stands behind the [Handsontable](https://handsontable.com/) data grid ## Documentation - [Client-side installation](https://handsontable.com/docs/hyperformula/guide/client-side-installation.md) - [Server-side installation](https://handsontable.com/docs/hyperformula/guide/server-side-installation.md) - [Basic usage](https://handsontable.com/docs/hyperformula/guide/basic-usage.md) - [Configuration options](https://handsontable.com/docs/hyperformula/guide/configuration-options.md) - [List of built-in functions](https://handsontable.com/docs/hyperformula/guide/built-in-functions.md) - [API Reference](https://handsontable.com/docs/hyperformula/api/) ## Integrations - [Integration with React](https://handsontable.com/docs/hyperformula/guide/integration-with-react.md#demo) - [Integration with Angular](https://handsontable.com/docs/hyperformula/guide/integration-with-angular.md#demo) - [Integration with Vue](https://handsontable.com/docs/hyperformula/guide/integration-with-vue.md#demo) - [Integration with Svelte](https://handsontable.com/docs/hyperformula/guide/integration-with-svelte.md#demo) ## Installation and usage Install the library from [npm](https://www.npmjs.com/package/hyperformula) like so: ```bash npm install hyperformula ``` Once installed, you can use it to develop applications tailored to your specific business needs. Here, we've used it to craft a form that calculates mortgage payments using the `PMT` formula. ```js import { HyperFormula } from 'hyperformula'; // Create a HyperFormula instance const hf = HyperFormula.buildEmpty({ licenseKey: 'gpl-v3' }); // Add an empty sheet const sheetName = hf.addSheet('Mortgage Calculator'); const sheetId = hf.getSheetId(sheetName); // Enter the mortgage parameters hf.addNamedExpression('AnnualInterestRate', '8%'); hf.addNamedExpression('NumberOfMonths', 360); hf.addNamedExpression('LoanAmount', 800000); // Use the PMT function to calculate the monthly payment hf.setCellContents({ sheet: sheetId, row: 0, col: 0 }, [['Monthly Payment', '=PMT(AnnualInterestRate/12, NumberOfMonths, -LoanAmount)']]); // Display the result console.log(`${hf.getCellValue({ sheet: sheetId, row: 0, col: 0 })}: ${hf.getCellValue({ sheet: sheetId, row: 0, col: 1 })}`); ``` [Run this code in StackBlitz](https://stackblitz.com/github/handsontable/hyperformula-demos/tree/3.5.x/mortgage-calculator) HyperFormula ships an official Claude skill and machine-readable docs, so your AI coding agent can scaffold, configure, and debug HyperFormula correctly. To install the skill in Claude Code, or to point Cursor, GitHub Copilot, or another agent at the docs, see [Set up your coding agent](https://handsontable.com/docs/hyperformula/guide/setup-coding-agent.md). You can also connect any MCP-capable agent to the first-party [docs MCP server](https://handsontable.com/docs/javascript-data-grid/docs-mcp-server/) — semantic search over the full HyperFormula and Handsontable knowledge base: docs guides, API reference, code recipes, release notes, blog posts, and GitHub issues, always current with the latest release. ## Contributing Contributions are welcome, but before you make them, please read the [Contributing Guide](https://handsontable.com/docs/hyperformula/guide/contributing.md) and accept the [Contributor License Agreement](https://goo.gl/forms/yuutGuN0RjsikVpM2). ## License HyperFormula is available under two different licenses: GPLv3 and proprietary. The proprietary license can be purchased by [contacting our team](https://handsontable.com/get-a-quote) at Handsontable. Copyright (c) Handsoncode --- ## Advanced usage URL: https://handsontable.com/docs/hyperformula/guide/advanced-usage.html # Advanced usage > By default, cells are identified using a `SimpleCellAddress` which > consists of a sheet ID, column ID, and row ID, like > this: `{ sheet: 0, col: 0, row: 0 }` > > Alternatively, you can work with the **A1 notation** known from > spreadsheets like Excel or Google Sheets. The API provides the helper > function `simpleCellAddressFromString` which you can use to > retrieve the `SimpleCellAddress` . The following example shows how to use formulas to find out which of the two Teams (A or B) is the winning one. You will do that by comparing the average scores of players in each team. The initial steps are the same as in the [basic example](https://handsontable.com/docs/hyperformula/guide/basic-usage.md). First, import HyperFormula and choose the configuration options: ```javascript import { HyperFormula } from 'hyperformula'; const options = { licenseKey: 'gpl-v3' }; ``` This time you will use the `buildFromEmpty` static method to initialize the engine: ```javascript // initiate the engine with no data const hfInstance = HyperFormula.buildEmpty(options); ``` Now, let's prepare some data. The first column will be players' IDs and the second column will be their scores. Then, you will define the formulas responsible for calculating the average scores. ```javascript // first column represents players' IDs // second column represents players' scores const playersA = [ ['1', '2'], ['2', '3'], ['3', '5'], ['4', '7'], ['5', '13'], ['6', '17'] ]; const playersB = [ ['7', '19'], ['8', '31'], ['9', '61'], ['10', '89'], ['11', '107'], ['12', '127'] ]; // in cell A1 a formula checks which team is the winning one // in cells A2 and A3 formulas calculate the average score of players const formulas = [ ['=IF(Formulas!A2>Formulas!A3,"TeamA","TeamB")'], ['=AVERAGE(TeamA!B1:B6)'], ['=AVERAGE(TeamB!B1:B6)'] ]; ``` Now prepare sheets and insert the data into them: ```javascript // add 'TeamA' sheet const sheetNameA = hfInstance.addSheet('TeamA'); // get the new sheet ID for further API calls const sheetIdA = hfInstance.getSheetId(sheetNameA); // insert playersA content into targeted 'TeamA' sheet hfInstance.setSheetContent(sheetIdA, playersA); // add 'TeamB' sheet const sheetNameB = hfInstance.addSheet('TeamB'); // get the new sheet ID for further API calls const sheetIdB = hfInstance.getSheetId(sheetNameB); // insert playersB content into targeted 'TeamB' sheet hfInstance.setSheetContent(sheetIdB, playersB); // check the content in the console output console.log(hfInstance.getAllSheetsValues()); ``` After setting everything up, you can add formulas: ```javascript // add a sheet named 'Formulas' const sheetNameC = hfInstance.addSheet('Formulas'); // get the new sheet ID for further API calls const sheetIdC = hfInstance.getSheetId(sheetNameC); // add formulas to that sheet hfInstance.setSheetContent(sheetIdC, formulas); ``` Almost done! Now, you can use the `getSheetValues` method to get all values including the calculated ones. Alternatively, you can use `getCellValue`to get the value from a specific cell. ```javascript // get all sheet values const sheetValues = hfInstance.getSheetValues(sheetIdC); // get the simple cell address of 'A1' from that sheet const simpleCellAddress = hfInstance.simpleCellAddressFromString('A1', sheetIdC); // check the winning team 🎉 const winningTeam = hfInstance.getCellValue(simpleCellAddress); // print the result to the console console.log(winningTeam) ``` --- ## HyperFormula AI SDK for Vercel URL: https://handsontable.com/docs/hyperformula/guide/ai-sdk.html # HyperFormula AI SDK for Vercel A [Vercel AI SDK](https://sdk.vercel.ai/docs) tool that gives your agents deterministic spreadsheet and formula computation — backed by HyperFormula's Excel-compatible engine. > **Not available yet — coming soon** > > This integration is on our roadmap and **cannot be installed or used today**. The API shown below is a preview and may still change before the first release. > > If you'd like to try it, [join the early access list](https://2fmjvg.share-eu1.hsforms.com/2e6drCkuLTn-1RuiYB91eJA) — we'll ping you the moment the first beta is ready, and your sign-up directly tells us how strongly to prioritize this integration. ## What it does - **Evaluate formulas deterministically** — your agent runs any Excel-compatible formula through HyperFormula instead of asking the LLM to do math. Results are exact, reproducible, and auditable. - **Read and write cells and ranges** — the agent inspects, populates, or modifies sheet data through typed tool calls. - **Trace dependencies** — precedents and dependents are surfaced so the agent can explain how every value was derived. - **423 built-in functions out of the box** — the agent has access to the full Excel-compatible function set (`SUM`, `VLOOKUP`, `IRR`, `INDEX/MATCH`, and the rest), no implementation work required. ## Example Using HyperFormula as a tool inside the Vercel AI SDK: ```js import { generateText } from 'ai'; import { openai } from '@ai-sdk/openai'; import HyperFormula from 'hyperformula'; import { createSpreadsheetTools } from 'hyperformula/ai'; // Build a workbook your agent can reason about. const hf = HyperFormula.buildFromArray([ ['Revenue', 100], ['Cost', 60], ['Profit', '=B1-B2'], ], { licenseKey: 'gpl-v3' }); // Pass the spreadsheet tools straight into generateText. const result = await generateText({ model: openai('gpt-4o'), tools: createSpreadsheetTools(hf), prompt: 'What drives the profit number, and what happens if revenue doubles?', }); ``` A single import, one extra line in `tools`, and the model can evaluate formulas, read ranges, and edit cells through the SDK — without inventing numbers. ## Use cases - **Explain the spreadsheet** — ask the agent what a workbook does, which cells are inputs, and how each output is derived; get answers grounded in real formula evaluation. - **What-if scenarios and forecasting** — the agent tweaks assumptions and reports how downstream results change, deterministically. - **Validate and clean data** — the agent scans ranges for errors, missing values, or inconsistencies and fixes them in place. - **Generate formulas from natural language** — the agent translates a plain-English calculation into a verified, working Excel formula. - **Financial modeling and reporting** — NPV, IRR, amortization, KPI rollups, and other quantitative workflows where the answer must be exact and auditable. ## Get early access > **Be the first to try it** > > We're actively building this integration. Drop your email and we'll notify you the moment the first beta lands — so you can try it before the public release. > > [Join the early access list →](https://2fmjvg.share-eu1.hsforms.com/2e6drCkuLTn-1RuiYB91eJA) ## Links - [Vercel AI SDK documentation](https://sdk.vercel.ai/docs) - [HyperFormula on GitHub](https://github.com/handsontable/hyperformula) - [HyperFormula on npm](https://www.npmjs.com/package/hyperformula) - [Built-in functions](https://handsontable.com/docs/hyperformula/guide/built-in-functions.md) - [Custom functions](https://handsontable.com/docs/hyperformula/guide/custom-functions.md) --- ## Array formulas URL: https://handsontable.com/docs/hyperformula/guide/arrays.html # Array formulas Use array formulas to perform an operation (or call a function) on multiple cells at a time. ## About arrays In HyperFormula, an array can be: * A range of cell addresses (e.g., `A1:A10`) * A result of an arithmetic operation (e.g., `5*A1:B5`) * A result of a function (e.g., `=ARRAYFORMULA(ARRAY_CONSTRAIN(A2:E5, 2, 2))`) * An **inline array**: an ad-hoc array that doesn't reference any range of cells (e.g., `{1, 3, 5}`) An array is inherently a two-dimensional object. `1`x`1` arrays are treated as single, zero-dimensional values (**scalars**). ### Inline arrays An inline array is defined by curly braces: `{ }`. It can contain one or more rows, separated by: - The [`arrayColumnSeparator`](https://handsontable.com/docs/hyperformula/api/classes/config.md#arraycolumnseparator) (default: `,`) - The [`arrayRowSeparator`](https://handsontable.com/docs/hyperformula/api/classes/config.md#arrayrowseparator) (default: `;`) Every row must be of equal length. > **Inline arrays are not recomputed after initialization.** > > If an inline array contains a cell reference, and the cell's value changes, the array is not updated. ``` = {1, 2, 3} // an inline array with a single row = {1, 2 ; 3, 4} // an inline array with two rows = SUM({1, 2, 3}) // an inline array as an argument of a function = {A1, A2} // when the values of A1 or A2 change, this inline array is not updated = {1, 2 ; 3} // an invalid inline array: two rows of different lengths ``` ## Array arithmetic mode To use array formulas in HyperFormula, you need to enable the **array arithmetic mode**. You can enable the array arithmetic mode: * [Locally](#enabling-the-array-arithmetic-mode-locally) (for an individual function or operation) * [Globally](#enabling-the-array-arithmetic-mode-globally) (for your HyperFormula instance) ### Enabling the array arithmetic mode locally To enable the array arithmetic mode once, within a particular function or formula, use the `ARRAYFORMULA` function: | Syntax | Example | |:--------------------------------------------------|:----------------------------------| | `ARRAYFORMULA(your_array_formula)` | `=ARRAYFORMULA(A2:A5*B2:B5)` | | `ARRAYFORMULA(YOUR_FUNCTION(your_array_formula))` | `=ARRAYFORMULA(ISEVEN(A2:A5*10))` | ### Enabling the array arithmetic mode globally To enable the array arithmetic mode by default, everywhere in your HyperFormula instance: * In your HyperFormula [configuration](https://handsontable.com/docs/hyperformula/api/interfaces/configparams.md#usearrayarithmetic), set the `useArrayArithmetic` option to `true`. With the array arithmetic mode enabled globally, you can operate on arrays without using the `ARRAYFORMULA` function: ``` =A2:A5*B2:B5 ISEVEN(A2:A5*10) ``` ## Array features Thanks to HyperFormula's built-in array features, you can: * [Operate on arrays](#operating-on-arrays) just like on [scalars](#about-arrays) * [Pass arrays to functions](#passing-arrays-to-scalar-functions-vectorization) that accept [scalars](#about-arrays) * [Broadcast](#broadcasting) smaller input arrays across larger output areas You can also: * Use the `FILTER` function to [filter an array](#filtering-an-array), based on boolean arrays * Use the `ARRAY_CONSTRAIN` function to [constrain an array's size](#constraining-an-arrays-size) ### Operating on arrays You can operate on arrays just like on single values. When the [array arithmetic mode](#array-arithmetic-mode) is enabled, each output array value is the result of your operation on the corresponding input array value. ``` =ARRAYFORMULA(A2:A5*B2:B5) // calculates: // =A2*B2 // =A3*B3 // =A4*B4 // =A5*B5 ``` ### Passing arrays to scalar functions (vectorization) When the [array arithmetic mode](#array-arithmetic-mode) is enabled, HyperFormula automatically _vectorizes_ most functions. As a consequence of that, you can pass arrays to functions that would normally accept [scalars](#about-arrays). The result would also be an array. ``` =ARRAYFORMULA(ISEVEN(A2:A5)) // calculates: // =ISEVEN(A2) // =ISEVEN(A3) // =ISEVEN(A4) // =ISEVEN(A5) ``` ### Broadcasting If an input array has a dimension of `1`, it's automatically repeated ("broadcast") on that dimension to match the size of the output. ``` =ARRAYFORMULA(ISEVEN(A2:A5*B2)) // calculates: // =ISEVEN(A2*B2) // =ISEVEN(A3*B2) // =ISEVEN(A4*B2) // =ISEVEN(A5*B2) ``` ### Filtering an array When the [array arithmetic mode](#array-arithmetic-mode) is enabled, you can filter an array, based on boolean arrays, using the `FILTER` function: | Syntax | Example | |:-----------------------------------------------------|:------------------------------------------------| | `FILTER(your_array, BoolArray1[, BoolArray2[, ...]]` | `=ARRAYFORMULA(FILTER(A2:A5*10), {1, 0, 0, 1})` | ### Constraining an array's size When the [array arithmetic mode](#array-arithmetic-mode) is enabled, you can constrain the size of the output array, using the `ARRAY_CONSTRAIN` function: | Syntax | Example | |:-------------------------------------------|:----------------------------------------------| | `ARRAY_CONSTRAIN(your_array,height,width)` | `=ARRAYFORMULA(ARRAY_CONSTRAIN(A2:E5, 2, 2))` | If your specified output array size is smaller than the input array size, only the corresponding top-left cells of the input array are taken into account. If your specified output array size is larger or equal to the input array size, no change is made. ## Array rules ### With the array arithmetic mode enabled When the [array arithmetic mode](#array-arithmetic-mode) is enabled, and you pass an array to a [scalar](#about-arrays) function, the following rules apply: * Array dimensions need to be consistent (e.g., every row needs to be of the same length). * If an input array value is missing (due to a difference in dimensions), the corresponding output array value is `#N/A`. * If a cell evaluates to an array, the array values are spilled into neighboring cells (unless the neighboring cells are already filled).
AllCellPrecedents={start}
let Q be an empty queue
Q.enqueue(start)
while Q is not empty do
cell := Q.dequeue()
S := getCellPrecedents(cell)
for all cells c in S do:
if c is not in AllCellPrecedents then:
insert w to AllCellPrecedents
Q.enqueue(c)
AllCellDependents={start}
let Q be an empty queue
Q.enqueue(start)
while Q is not empty do
cell := Q.dequeue()
S := getCellDependents(cell)
for all cells c in S do:
if c is not in AllCellDependents then:
insert w to AllCellDependents
Q.enqueue(c)
| {{ cell }} | }
| {{ cell }} |
| {String(cell ?? '')} | ))}
Result: {result}
{/if}| {#if hf.doesCellHaveFormula({ sheet: sheetId, row: r, col: c })} {hf.getCellFormula({ sheet: sheetId, row: r, col: c })} {:else} {hf.getCellValue({ sheet: sheetId, row: r, col: c })} {/if} | {/each}
Result: {result}
{/if} ``` ## Next steps - [Configuration options](https://handsontable.com/docs/hyperformula/guide/configuration-options.md) — full list of `buildFromArray` / `buildEmpty` options - [Basic operations](https://handsontable.com/docs/hyperformula/guide/basic-operations.md) — CRUD on cells, rows, columns, sheets - [Advanced usage](https://handsontable.com/docs/hyperformula/guide/advanced-usage.md) — multi-sheet workbooks, named expressions - [Custom functions](https://handsontable.com/docs/hyperformula/guide/custom-functions.md) — register your own formulas ## Demo For a more advanced example, check out the [Svelte demo on Stackblitz](https://stackblitz.com/github/handsontable/hyperformula-demos/tree/3.5.x/svelte-demo?v=30%2F10%2F2026%2006%3A35%3A01). --- ## Integration with Vue URL: https://handsontable.com/docs/hyperformula/guide/integration-with-vue.html # Integration with Vue The HyperFormula API is identical in a Vue 3 app and in plain JavaScript. This guide demonstrates how HyperFormula integrates with the Vue reactivity system and how to surface its values in the template. Install with `npm install hyperformula`. For other options, see the [client-side installation](https://handsontable.com/docs/hyperformula/guide/client-side-installation.md) section. > **TypeScript** > > All examples use TypeScript. Remove the type annotations to use plain JavaScript. ## Basic usage Pass the HyperFormula instance through Vue's [`markRaw`](https://vuejs.org/api/reactivity-advanced.html#markraw) to opt it out of the reactivity system (see [Troubleshooting](#vue-reactivity-issues) below for why this matters). Hold derived data in `ref` so the template updates when you reassign the ref's `.value`. ```vue| {{ cell }} |
| Precedence | Operator | Description |
|---|---|---|
| 1 |
: (colon) , (comma) (space) |
Reference operators: range (colon), union (comma), intersection (space). Currently supported by HyperFormula only at the grammar level of a function. |
| 2 | – | Negation |
| 3 | % | Percent |
| 4 | ^ | Exponentiation |
| 5 | * and / | Multiplication and division |
| 6 | + and – | Addition and subtraction |
| 7 | & (ampersand) | Concatenation of two or more text strings |
| 8 |
< (less than) = (equal to) > (greater than) <= (less than or equal to) >= (greater than or equal to) <> (not equal to) |
Comparison |
| Feature | Maximum limit |
|---|---|
| Number of cells |
Limited by system resources (JavaScript) Can be set in the configuration:
|
| Number of nested levels of functions | 120 |
| Earliest date allowed for the calculation | December 30, 1899 |
| Latest date allowed for the calculation | December 31, 9999 |
| Number of named expressions | Limited by system resources (JavaScript) |
| Characters in a cell | Limited by system resources (JavaScript) |
| Characters in a named expression | Limited by system resources (JavaScript) |
| Characters in a sheet name | Limited by system resources (JavaScript) |
| Characters in a column name | Depends on the configuration of MaxColumns |
| Number of sheets in a workbook | Limited by system resources (JavaScript) |
| Number of custom functions | Limited by system resources (JavaScript) |
| Undo levels | Limited by the configuration - undoLimit (default: 20) |
| Number of elements in a batch operation | Limited by system resources (JavaScript) |