Version 7.0.8
Every way to install TrueCalc.
One engine on npm, JSR and crates.io. 491 Google Sheets functions plus 27 timezone extensions of our own. Every command below was run before it was written down.
That is the published package running in your browser — the same artifact npm install gives you. Try ="10" + 5, or =TEXT(DATE(2026,13,1), "yyyy-mm-dd").
JavaScript & TypeScript
WebAssembly. Runs in the browser, Node and Deno — no server, no network.
npm
npm install @truecalc/coreNode 24+ — on Node 22 run with `--experimental-wasm-modules`. Bundlers need a WASM plugin: vite-plugin-wasm for Vite, `experiments.asyncWebAssembly` for webpack 5.
import { evaluate, list_functions } from '@truecalc/core';
evaluate('SUM(A1, B1)', { A1: 100, B1: 200 });
// => { type: 'number', value: 300 }
evaluate('IF(A1 > 0, "yes", "no")', { A1: 1 });
// => { type: 'text', value: 'yes' }
list_functions().length;
// => 518Rust
The engine itself. Stateless, no allocator surprises, bring your own data.
cargo
cargo add truecalc-coreErrors are values, not `Err` — a division by zero returns `Value::Error(ErrorKind::DivByZero)`, exactly as a cell would.
use std::collections::HashMap;
use truecalc_core::{Engine, Value};
let engine = Engine::sheets();
let mut vars = HashMap::new();
vars.insert("A1".to_string(), Value::Number(100.0));
vars.insert("B1".to_string(), Value::Number(200.0));
let result = engine.evaluate("=SUM(A1,B1)", &vars);
assert_eq!(result, Value::Number(300.0));MCP server
Give Claude, Cursor or any MCP client a calc engine it cannot get wrong.
cargo
cargo install truecalc-mcpTwelve tools over stdio, including a stateful workbook your agent can keep across a whole conversation.
// claude mcp add truecalc -- ~/.cargo/bin/truecalc-mcp
// …or write it yourself, in .mcp.json:
{
"mcpServers": {
"truecalc": {
"type": "stdio",
"command": "/Users/you/.cargo/bin/truecalc-mcp"
}
}
}Deno
On JSR, and the only runtime that needs no permission flags at all.
deno
deno add jsr:@truecalc/coreNo --allow-net, no --allow-read. The engine is compiled into the module graph, so `deno run` is the whole command.
import { evaluate, createEngine } from '@truecalc/core';
evaluate('=SUM(A1,A2)', { A1: 10, A2: 20 });
// => { type: 'number', value: 30 }
createEngine('google-sheets').evaluate('=UPPER("ok")', {});
// => { type: 'text', value: 'OK' }@truecalc/workbook
A whole workbook in the browser — sheets, a dependency graph, and recalc.
npm
npm install @truecalc/workbookOn Node, hand `init()` the wasm bytes directly — Node cannot fetch a file:// URL. See the workbook-node example in the repo.
import init, { JsWorkbook } from '@truecalc/workbook';
await init();
const wb = new JsWorkbook('sheets');
wb.addSheet('Sheet1');
wb.set('Sheet1', 'A1', '10');
wb.set('Sheet1', 'A2', '=A1*2');
// The context pins NOW, TODAY and RAND, so the same workbook
// plus the same context is always the same grid.
wb.recalc(JSON.stringify({ timestamp_ms: 0, timezone: 'UTC', rng_seed: 0 }));
// resolved() hands back a JSON string, not an object.
JSON.parse(wb.resolved('Sheet1', 'A2'));
// => { type: 'number', value: 20 }truecalc-workbook
The same workbook, in Rust. Canonical JSON in, canonical JSON out.
cargo
cargo add truecalc-workbookSerializes to RFC 8785 canonical JSON, which is what makes a workbook byte-comparable across languages and across years.
use truecalc_workbook::{
Address, CellInput, EngineFlavor, RecalcContext, Value, Workbook, Worksheet,
};
let mut wb = Workbook::new(EngineFlavor::Sheets);
wb.add_sheet(Worksheet::new("Budget")).unwrap();
let a1 = Address::from_a1("A1").unwrap();
let a2 = Address::from_a1("A2").unwrap();
let a3 = Address::from_a1("A3").unwrap();
wb.set("Budget", a1, CellInput::Literal(Value::Number(1000.0))).unwrap();
wb.set("Budget", a2, CellInput::Literal(Value::Number(500.0))).unwrap();
wb.set("Budget", a3, CellInput::Formula("=SUM(A1:A2)".to_string())).unwrap();
// RecalcContext::new(unix_ms, iana_tz, rng_seed)
let ctx = RecalcContext::new(1_780_000_000_000, "Etc/GMT", 0).unwrap();
wb.recalc(&ctx);
assert_eq!(wb.get("Budget", a3).unwrap().value(), &Value::Number(1500.0));Not yet
What you cannot install today.
Listed so you can plan around it. Neither of these has an install command because neither exists yet — when they ship, they will appear above with the rest.
Python
In developmentNative bindings for notebooks and data pipelines.
In development. The bindings build from source in the repo, but nothing is published to PyPI yet — so there is no install command to give you.
Hosted API & MCP
In developmentWorkbooks that outlive the request, reachable from anywhere, with no infrastructure of yours.
Not yet shipped. Everything above runs entirely on your machine, with no account and no network.
Something not working?
A result that disagrees with Google Sheets is a bug, not a limitation. Open an issue with the formula and we will add it to the conformance corpus.