Workbook Operations
Workbook APIs expose structural edits in addition to cell mutation and recalculation. WASM, Native Node, and Python expose broad Workbook APIs through the same C ABI; the CLI focuses on recalculation and inspection rather than fine-grained edits.
Glossary: zero-based coordinates
Binding addresses are (sheet, row, col) with all indices starting at 0. Sheet1!A1 is (0, 0, 0). The numeric form avoids locale-specific address parsing and matches the C ABI. Use A1 text only where a CLI or formula explicitly expects it.
Sheets
const wb = Module.Workbook.createDefault()
try {
wb.addSheet('Inputs')
wb.renameSheet(0, 'Model')
wb.moveSheet(1, 0)
wb.removeSheet(1)
} finally {
wb.delete()
}Python uses the same zero-based coordinate model:
with Workbook.create_default() as wb:
wb.add_sheet("Inputs")
print(wb.sheet_count())
print(wb.sheet_name(0))Cells
Set values by kind, then recalculate:
wb.setNumber(0, 0, 0, 10)
wb.setBool(0, 0, 1, true)
wb.setText(0, 0, 2, 'sku-001')
wb.setFormula(0, 0, 3, '=SUM(A1:A10)')
wb.setBlank(0, 0, 4)
wb.recalc()Read calculated values back as kind-tagged structs:
const value = wb.getValue(0, 0, 3)
if (value.kind === ValueKind.Number) console.log(value.number)Setting a formula does not evaluate it
setFormula() only mutates the model. The result is Blank until recalc() (or partialRecalc()) is called. Hosts that read values after edits should always trigger a recalc.
Structure
Row and column insert / delete operations rewrite affected formulas automatically:
wb.insertRows(/*sheet*/ 0, /*startRow*/ 5, /*count*/ 2)
wb.deleteCols(/*sheet*/ 0, /*startCol*/ 3, /*count*/ 1)References inside formulas that move with the inserted / deleted range are shifted; references that anchor outside the range are preserved.
Layout, styles, and metadata
WASM, Native Node, and Python expose workbook operations such as:
- row / column insert / delete with formula rewriting,
- defined names,
- tables,
- passthrough OOXML parts,
- pivot table layout projection,
- conditional formatting read / evaluate / write subset,
- sheet view, freeze panes, hidden tabs,
- sheet protection metadata,
- row / column layout overrides,
- styles, number formats, fonts, fills, borders,
- merges, comments, hyperlinks, and data validations,
- precedent / dependent tracing,
- function metadata and function-name helpers,
- dynamic-array spill information.
Conditional-format rule creation (addConditionalFormat() / fm_sheet_cf_add_rule) also returns the new rule's flattened index, which makes host-side UI selection and follow-up edits easier.
WASM and Native Node additionally expose comment enumeration — getComments(sheet) (backed by fm_sheet_get_comment_count / fm_sheet_get_comment_at_index) lists every comment on a sheet, including comments anchored on otherwise-empty cells. Python can read and write a comment at a known (sheet, row, col) via get_comment() / set_comment(), but has no sheet-wide enumeration call — walk the used range and call get_comment() per cell if you need a full list from Python.
Host applications that supply their own localized function metadata can merge it over the engine's structural catalog with mergeFunctionMetadata() (Node, exported from both @libraz/formulon and the native package) / merge_function_metadata() (Python), added in v0.9.5. It is a pure helper — precedence runs locale-override, then entry-default, then the engine value — layered over functionMetadata(), which now also recognizes lazy-dispatch forms (XLOOKUP, SUMIFS, …) and parser special forms (LET, LAMBDA), and reports unbounded arity as null / None.
Ad-hoc formula evaluation
WASM and Native Node (C API) additionally expose read-only ad-hoc formula evaluation. evaluateFormulaText() and evaluateConditionalFormula() — Node addon, WASM, and C API only, not on Python — answer "what would this formula return here?" without writing the formula into a cell first:
const result = wb.evaluateFormulaText(/*sheet*/ 0, /*row*/ 0, /*col*/ 0, '=A1+B1')
if (result.status.ok && result.value.kind === ValueKind.Number) {
console.log(result.value.number)
}This is read-only: it does not mutate the workbook, write a value anywhere, or join the dependency graph — nothing here becomes dirty on a later edit. Array/spill results are also reduced to their top-left element: evaluating =SEQUENCE(3) this way returns a single number, not a 3-row spill. That is a deliberate Phase 1 API shape, not a regression — a real cell containing =SEQUENCE(3) still spills normally. See Dynamic arrays for how spilling works when the formula is actually written into a cell.
Since v0.9.5, evaluateFormulaArray() (Node addon, WASM, and C API) — and evaluate_formula_array() on Python — answers the same read-only question but returns the whole Array result (an EvalArrayResult) instead of reducing a dynamic-array / spilled formula to its top-left element. Evaluating =SEQUENCE(3) this way yields all three rows. It carries the same read-only, no-mutation, and self-reference caveats as evaluateFormulaText(), and is the one ad-hoc evaluation call Python does have — the scalar evaluateFormulaText() / evaluateConditionalFormula() pair remains Node/WASM/C-API only.
evaluateConditionalFormula() follows the same read-only rule, additionally shifting relative references from the rule's anchor and applying Excel's CF-predicate coercion (error / blank / text / numeric-zero are false; any other number is true), so the result matches what a real CF rule would evaluate to at that cell.
The normal edit path and the ad-hoc path answer different questions — the first commits a value you can read again later, the second is a disposable "what if" query:
- setFormula()
- recalc()
- getValue()mutates the model; result stays until the next edit
- evaluateFormulaText()no mutation · no dependency-graph entry
- Scalar resultarray/spill results reduced to the top-left element
The CLI is intentionally narrower. It is a command surface for eval, recalc, and dump, not a fine-grained workbook-editing API. For application embedding, choose WASM, Native Node, or Python.
Discovering what is implemented
Both Module.functionNames() (WASM) and formulon_function_lookup (MCP) enumerate registered functions at runtime. Use them to verify a target Excel version's surface rather than reading the static docs.
Read next
- Recalculation — when edits become visible values.
- Surface matrix — what each binding exposes.
- Compatibility / Errors — what edits to expect on malformed input.