Skip to content

Bindings ​

Bindings expose workbook operations to host environments while keeping calculation in the core. Each binding adapts host types and operations, then calls the C ABI.

Glossary: binding

A thin per-host layer that translates host types (Uint8Array, bytes, bytearray, byte pointer + length) into engine inputs and engine outputs back into host types. Bindings do not implement formula semantics — they shape data and manage lifetimes.

Host typesBindingsBoundaryCoreUint8Array / BufferWASM, Native Nodebytes / bytearrayPythonByte pointer +lengthC ABI inputJSON inputsMCP toolsWASMSerial and pthread entries@libraz/formulon-nativeBuilt from source, not on npmPythonContext manager, bytesCLIargv, stdio, exit codesMCPJSON in and out, sessionsC ABIThe compatibility boundaryC++17 coreParser, evaluator, calc graph, file IOHost typesBindingsBoundaryCoreUint8Array / BufferWASM, Native Nodebytes / bytearrayPythonByte pointer + lengthC ABI inputJSON inputsMCP toolsWASMSerial and pthread entries@libraz/formulon-nativeBuilt from source, not on npmPythonContext manager, bytesCLIargv, stdio, exit codesMCPJSON in and out, sessionsC ABIThe compatibility boundaryC++17 coreParser, evaluator, calc graph, file IO
A binding only translates host types and lifetimes; calculation always happens in the core behind the C ABI.

Responsibilities ​

  • Convert host buffers to workbook bytes accepted by the C ABI.
  • Manage workbook handles and lifetimes (delete() in WASM, context manager in Python, dispose() plus GC fallback in Native Node, CLI process lifetime, MCP session lifetime).
  • Convert spreadsheet values to host values, preserving ValueKind so cell errors remain values rather than exceptions.
  • Surface calculation and IO errors without losing spreadsheet error values.
  • Expose the function and structural API documented under API per host.

Locale behavior stays in the core. The C ABI and the JS/Python bindings pass full Excel profile ids for profile selection, function-name translation, formula localization, and locale facts. Human-readable function metadata remains a host concern and is locale-invariant in the engine catalog.

Non-responsibilities ​

Bindings should not:

  • implement formula semantics (the parser / evaluator lives in the core),
  • duplicate workbook parsing (the OOXML / XLSB readers live in the core),
  • add profile-specific behavior (profiles are workbook state, set through the C ABI),
  • introduce a separate dirty-set, dependency graph, or recalc scheduler (all of those belong to the core).

Don't reimplement Excel in the binding

If a binding is tempted to special-case a function result or coerce a value differently than the core, the right fix is in the core: add the case to the evaluator, add an oracle golden, and let every binding pick up the change at once. Per-binding patches drift fast.

The npm WASM binding publishes a single-threaded @libraz/formulon entry and a pthread @libraz/formulon/threads entry. They share the C ABI, workbook API, and TypeScript declarations; only the pthread entry supports worker-based parallel recalculation.

What this looks like in practice ​

BindingHost idioms it handlesWhat it never touches
WASMUint8Array, status-bearing return values, ValueKind enum, async module factory, serial or pthread entry selectionFunction semantics, file parsing, calculation graph
Native NodeN-API Buffer, sync API shape, dispose() and memoryUsage()Function semantics, file parsing, calculation graph
Pythonbytes, context manager, FormulonError, Value.to_python()Function semantics, file parsing, calculation graph
CLIargv, stdin / stdout / stderr, exit codesFunction semantics, file parsing, calculation graph
MCPJSON inputs / outputs, session map, allowlist dispatchFunction semantics, file parsing, calculation graph