Formulas
Per-cell formulas with automatic dependency tracking, cycle detection, and live recalculation.
Any cell can hold a formula instead of a plain value — a string starting with = that references other cells
and recomputes automatically when they change, backed by a dependency graph (not a full recalculation on every
edit).
Writing a formula
A formula is just a cell value that starts with =. Typing one directly into an editable cell works exactly
like a spreadsheet — no separate "formula mode" to opt into:
api.setCellValue('row-1', 'total', '=[row-1:price] * [row-1:quantity]');Cell references use [rowId:colField] — the grid's own row id and column field, not spreadsheet A1 notation.
Reference any cell in the grid, including ones in other columns or other rows:
api.setCellValue('row-3', 'variance', '=[row-3:actual] - [row-3:budget]');Functions
SUM, AVERAGE, MIN, and MAX take a comma-separated argument list — each argument can be a cell reference,
a literal number, or a nested expression:
api.setCellValue('row-1', 'q1Total', '=SUM([row-1:jan], [row-1:feb], [row-1:mar])');
api.setCellValue('row-1', 'avgDeal', '=AVERAGE([row-1:deal1], [row-1:deal2], [row-1:deal3])');There's no range syntax (no SUM(A1:A10)) — list the cells explicitly, or compute the aggregate on your own data
and write the result with setCellValue if the set of contributing cells is large or dynamic.
Arithmetic supports +, -, *, /, parentheses, and unary minus, evaluated by a dedicated safe parser — never
eval().
Reading values
getCellValue always returns the resolved, computed value — you never need to know whether a cell holds a
formula to read it:
const total = api.getCellValue('row-1', 'total'); // computed number, not "=[row-1:price] * [row-1:quantity]"Use the formula-specific methods when you need the formula itself, or want to set/clear one without going through a plain value edit:
api.getFormula('row-1', 'total'); // '=[row-1:price] * [row-1:quantity]' | undefined
api.hasFormula('row-1', 'total'); // boolean
api.setFormula('row-1', 'total', '=[row-1:price] * [row-1:quantity]');
api.clearFormula('row-1', 'total'); // reverts the cell to its last raw (non-formula) valueDependency tracking & recalculation
Every formula's references are parsed into a dependency graph. Editing [row-1:price] automatically invalidates
and recomputes total — and anything else that depends on total — without recomputing the rest of the grid.
Results are cached until a dependency actually changes.
Circular references
Setting a formula that would create a cycle (total depends on price, price depends on total) throws immediately, synchronously, from the
call that introduces it — the formula is rejected, not silently applied. A cycle that could somehow only appear at evaluation time surfaces as a
thrown error from that evaluation instead of an infinite loop.
Errors
An expression that fails to evaluate (a non-numeric reference used arithmetically, for example) resolves to a
string like #VALUE! (reason) rather than throwing — so a bad formula shows up visibly in the cell instead of
crashing the render:
api.getCellValue('row-1', 'total'); // '#VALUE! (Unexpected token...)' when the formula itself is malformedCombining with columns
Formulas work with any column — valueFormatter still controls how the computed result is displayed, and
onCopy/onPaste still control clipboard behavior:
const columns: ColumnDef<Person>[] = [
{
field: 'score',
header: 'Total',
valueFormatter: ({ value }) => `$${Number(value).toFixed(2)}`,
},
];See Columns for the full column configuration surface, and Grid API
for the complete GridApi reference.
Last updated on