Skip to content

Architecture

Formulon is organized around a single calculation core with thin packaging layers. Every host surface — WASM, Native Node, Python, CLI, MCP, formulon-cell — sits on top of the same C++17 core through the C ABI.

Glossary: C ABI layer

A flat C function interface that exposes the workbook model, evaluator, and IO to non-C++ hosts. It is the only stable boundary; bindings call into it, but only the core implements it. See Bindings.

Glossary: workbook model

The in-memory representation of an opened workbook — sheets, cells, styles, defined names, tables, dependency graph, dirty set, profile binding, and the workbook-level engine state needed to recalculate. Bindings hold a handle to the model, never the underlying bytes after parsing.

What lives where

LayerOwns
Host APILanguage-specific surface (JS / Python / CLI / MCP tools / cell UI)
C ABI / bindingLifetime management, host value ↔ engine value translation
Workbook modelSheets, cells, styles, dependency graph, dirty state, profile
Parser / evaluatorFunction catalog, tree-walker, bytecode VM, error propagation
File format layerOOXML, XLSB readers and writers, passthrough preservation
Oracle / parity testsCaptured Excel values, cross-surface agreement

The core owns workbook state, formula semantics, file parsing, dependency tracking, and recalculation. Bindings should translate host values and lifetime management without changing calculation behavior.

Why the split

  • Determinism: a single calculation source means all surfaces produce the same values on the same profile.
  • Embedding: the core has no Node, Python, or browser assumptions, so the same binary serves all three.
  • Testing: oracle data is compared against the engine, not against per-binding logic.
  • C++ core — internal conventions of the calculation core.
  • Bindings — responsibilities and non-responsibilities.
  • Build from source — how the artifacts are produced.