Excel-scale recalculation in WebAssembly.
Titan compiles formulas into bytecode and stores cells in contiguous 32×32 Struct-of-Arrays chunks inside WASM linear memory. No JavaScript object churn, no GC pauses, and sub-millisecond reactive updates.
npm install titan-engine
- Memory Layout
- 32×32 SoA Chunks
- Execution
- Pratt AST → Stack VM
- Graph Solver
- Bipartite Kahn DAG
- Standard Library
- 43 Native Functions
Why JavaScript spreadsheets stall—and how Titan avoids it.
Most web spreadsheets represent every cell as a heap-allocated JavaScript object and serialize results across boundaries. Titan keeps the entire calculation lifecycle inside flat WebAssembly arrays.
Struct-of-Arrays Chunk Memory
Sheets are partitioned into sparse 32×32 chunks (1,024 cells). Each chunk separates cell tags from 64-bit payloads in contiguous arrays so sequential column scans stay in L1 cache and JavaScript reads via zero-copy Float64Array views.
Pratt AST to Stack Bytecode with Lazy Ranges
Formulas compile once into flat OpCode vectors. Ranges push lightweight 5-integer RangeRef descriptors onto the VM stack rather than allocating intermediate arrays, and IF / IFERROR compile to native jump instructions (JmpIfFalse, TryCatch, EndTry).
30,000 Graph Edges Instead of 200,000,000
When 20,000 cells in A1:B10000 update alongside 10,000 VLOOKUP or SUMIF formulas, naive engines build 20,000 × 10,000 = 200,000,000 cell-to-cell dependency edges. Titan condenses ranges into intermediate DAG nodes during Kahn's topological sort—visiting each range's dependents exactly once when its in-degree reaches zero.
Head-to-Head vs. HyperFormula
Measured in Chrome on macOS · Run the suite yourself in your own browser tab.
| Scenario | Scale | HyperFormula | Titan (WASM) | Speedup |
|---|---|---|---|---|
| VLOOKUP Scan | 10,000 lookups | 11,694.8 ms | 58.6 ms | 199.6× faster |
| Conditional SUMIF | 10,000 formulas | 36,845.9 ms | 300.7 ms | 122.5× faster |
| Multi-Criteria SUMIFS | 5,000 formulas | 14,847.3 ms | 115.0 ms | 129.1× faster |
| Formula Compilation | 30,000 unique | 561.3 ms | 71.4 ms | 7.9× faster |
| Matrix Broadcasting | 100,000 evals | 34.2 ms | 9.2 ms | 3.7× faster |
| Deep Topo Cascade | 20,000 chain | 27.4 ms | 8.5 ms | 3.2× faster |
| Raw Cell Allocation | 100,000 cells | 175.1 ms | 54.3 ms | 3.2× faster |
Drop-In Ergonomics
Polymorphic A1 or {row, col} addressing with reactive delta subscriptions.
import { initTitan } from 'titan-engine';
const Titan = await initTitan();
const engine = new Titan();
const sheet = engine.addSheet("Revenue");
// Subscribe to cascading cell changes
engine.onCellsChanged((deltas) => {
for (const { a1, cell } of deltas) {
console.log(`${a1} -> ${cell.display}`);
}
});
// Batch-insert a 2D range and evaluate DAG once
sheet.setRange("A1", [
["Q1", 12500],
["Q2", 18400],
["Sum", "=SUM(B1:B2)"],
["Tax", "=IF(B3>25000, B3*0.2, 0)"]
]);