Formualizer Docs
Guides

Custom Functions (Rust, Python, JS)

Register workbook-local callbacks with consistent semantics across Rust, Python, and JS/WASM.

Formualizer exposes the same custom-function model in all runtimes: register a workbook-local callback, call it from formulas, and unregister when done.

Semantics that are the same across runtimes

  • Function names are case-insensitive and canonicalized to uppercase (my_fn, MY_FN, My_Fn all map to one entry).
  • Resolution is workbook-local first, then global built-ins.
  • Built-in override is blocked by default; opt in with allow_override_builtin (Rust/Python) or allowOverrideBuiltin (JS).
  • Arity is validated before callback execution (min_args/max_args style options).
  • Range arguments are materialized as 2D arrays (LiteralValue::Array in Rust, nested lists in Python, nested arrays in JS).
  • Returning an array spills into the grid using normal dynamic-array behavior.

Register and call a custom function

Register a callback, then use it in a formula
use formualizer_common::LiteralValue;use formualizer_workbook::{CustomFnOptions, Workbook};use std::sync::Arc;let mut wb = Workbook::new();wb.add_sheet("Sheet1")?;wb.set_values(  "Sheet1", 1, 1,  &[      vec![LiteralValue::Number(1.0), LiteralValue::Number(2.0)],      vec![LiteralValue::Number(3.0), LiteralValue::Number(4.0)],  ],)?;wb.register_custom_function(  "range_total",  CustomFnOptions { min_args: 1, max_args: Some(1), ..Default::default() },  Arc::new(|args: &[LiteralValue]| {      let total = match &args[0] {          LiteralValue::Array(rows) => rows.iter().flatten().fold(0.0, |acc, v| {              acc + match v {                  LiteralValue::Number(n) => *n,                  LiteralValue::Int(i) => *i as f64,                  _ => 0.0,              }          }),          _ => 0.0,      };      Ok(LiteralValue::Number(total))  }),)?;wb.set_formula("Sheet1", 1, 3, "=RANGE_TOTAL(A1:B2)")?;assert_eq!(wb.evaluate_cell("Sheet1", 1, 3)?, LiteralValue::Number(10.0));

Quick verification commands

cargo run -p formualizer-workbook --example custom_function_registration
python bindings/python/examples/custom_function_registration.py
cd bindings/wasm && npm run build && node examples/custom-function-registration.mjs

On this page