Skip to content

Formula proof paths

# Recalculate XLSX formulas or give agents a workbook API.

Pick the narrow command for the job. Both paths prove fresh formula readback before adoption.

XLSX formulas stale? Recalculate in Node `npx --package @bilig/xlsx-formula-recalc xlsx-recalc --demo --json` Fresh cached values without Excel, LibreOffice, or browser automation. Agent needs spreadsheet tools? Create a WorkPaper tool loop `npm create @bilig/workpaper@latest pricing-agent -- --agent` Write inputs, recalculate, verify readback, and persist workbook JSON.
Choose a package XLSX npm WorkPaper npm Ask docs View GitHub

Package chooser

## Install the package that matches the job.

Start with the narrow npm package for your problem. The full headless runtime is still available when you need lower-level APIs or agent metadata.

highest-traffic entry SheetJS or XLSX inputs changed and formulas are stale?

Start with the SheetJS-named package before moving to a full workbook runtime. The bridge example covers SheetJS, xlsx-populate, and ExcelJS with one workbook.

    npx --package @bilig/sheetjs-formula-recalc sheetjs-recalc --demo --json

    npx --package @bilig/xlsx-formula-recalc xlsx-recalc --demo --json

    npx --package @bilig/sheetjs-formula-recalc sheetjs-recalc pricing.xlsx \
      --set Inputs!B2=48 \
      --read Summary!B7 \
      --out pricing.recalculated.xlsx \
      --json

workpaper `npm install @bilig/workpaper` Formula workbook state for Node services, queue workers, route handlers, tests, and agent tools. agent `npm create @bilig/workpaper@latest pricing-agent -- --agent` Build an agent spreadsheet tool that writes inputs, recalculates formulas, verifies readback, and persists state. xlsx `npm install @bilig/xlsx-formula-recalc` Edit XLSX inputs, recalculate formulas in Node, read proof values, and export the updated workbook. sheetjs `npm install @bilig/sheetjs-formula-recalc` Keep SheetJS / xlsx for file I/O and add the live formula-readback bridge after input edits. exceljs `npm install exceljs @bilig/exceljs-formula-recalc` Keep ExcelJS for workbook files and add recalculated formula readback when cached values are stale. runtime `npm install @bilig/headless` Use the full runtime package for lower-level subpaths, provenance checks, skill metadata, and MCP tooling.

When it fits

## Stop translating workbook logic into one-off code.

Pricing rules, import checks, payouts, and budget models often start life in cells. If that shape is still the clearest source of truth, keep it and run it from Node.

01 / create

### Build the workbook model.

Start from arrays, records, CSV-shaped data, or saved WorkPaper JSON.

02 / edit

### Write the input cell.

Update a quantity, rate, assumption, imported value, or threshold.

03 / read

### Read the calculated value.

Use the value the workbook produced after the input changed.

04 / save

### Save the document.

Persist sheets, formulas, and config as JSON between runs.

Quickstart

## Create a workbook in a blank Node project.

This installs the package, changes one input, reads the calculated total, saves JSON, and restores the workbook.

### Blank Node project

terminal Node.js 22+

    mkdir bilig-headless-eval
    cd bilig-headless-eval
    npm init -y
    npm pkg set type=module
    npm install @bilig/workpaper
    npm install -D tsx typescript @types/node
    curl -fsSLo quickstart.ts \
      https://proompteng.github.io/bilig/npm-eval.ts
    npx tsx quickstart.ts

More TypeScript examples live in examples/headless-workpaper , examples/serverless-workpaper-api, and examples/xlsx-recalculation-node.

quickstart.ts TypeScript

    import {
      WorkPaper,
      createWorkPaperFromDocument,
      exportWorkPaperDocument,
      parseWorkPaperDocument,
      serializeWorkPaperDocument,
    } from "@bilig/workpaper";

    const workbook = WorkPaper.buildFromSheets({
      Inputs: [
        ["Metric", "Value"],
        ["Customers", 20],
        ["Average revenue", 1200],
      ],
      Summary: [
        ["Metric", "Value"],
        ["Revenue", "=Inputs!B2*Inputs!B3"],
      ],
    });

    const inputs = workbook.getSheetId("Inputs");
    const summary = workbook.getSheetId("Summary");
    if (inputs === undefined || summary === undefined) {
      throw new Error("Missing sheet");
    }

    const before = readNumber(workbook.getCellValue({ sheet: summary, row: 1, col: 1 }));
    workbook.setCellContents({ sheet: inputs, row: 1, col: 1 }, 32);
    const after = readNumber(workbook.getCellValue({ sheet: summary, row: 1, col: 1 }));

    const saved = serializeWorkPaperDocument(exportWorkPaperDocument(workbook, { includeConfig: true }));
    const restored = createWorkPaperFromDocument(parseWorkPaperDocument(saved));
    const restoredSummary = restored.getSheetId("Summary");
    if (restoredSummary === undefined) {
      throw new Error("Missing restored Summary sheet");
    }

    const afterRestore = readNumber(restored.getCellValue({ sheet: restoredSummary, row: 1, col: 1 }));
    console.log({ before, after, afterRestore, verified: after === afterRestore });

    function readNumber(cell: unknown): number {
      if (typeof cell === "object" && cell !== null && typeof (cell as { value: unknown }).value === "number") {
        return (cell as { value: number }).value;
      }
      throw new Error(`Expected numeric cell value, got ${JSON.stringify(cell)}`);
    }

Where it runs

## Put the workbook behind the code that owns the workflow.

Route handler, queue worker, CLI, or MCP server: load the workbook, edit cells, read results, and save state.

fit Why use Bilig? Use it when spreadsheet logic needs API readback, tests, persistence, and agent-readable proof. service Node service WorkPaper recipe Load state, change an input, read the output, save JSON. proof Stop driving spreadsheets with screenshots Use a WorkPaper API when code needs formula readback, persistence, and restore proof. show hn Formula workbooks for Node services One npm check, visible benchmark caveat, and a concrete feedback ask. backend Server-side spreadsheet automation Run formulas inside a Node service without a browser grid. sheets api Google Sheets API boundary Use a hosted sheet for collaboration; use WorkPaper when a Node service owns formula state. graph api Microsoft Graph Excel recalculation boundary Use Excel Online for exact behavior; use WorkPaper when a Node service owns formula state. route Serverless WorkPaper API route Start with quote approval: write Inputs!B2:B6, recalc formulas, persist JSON, reload proof. frameworks Express, Fastify, Hono, Oak, Hapi, and AdonisJS adapters Keep framework glue small and leave formula work in the WorkPaper. agent Agent tool-calling recipe Expose workbook reads, writes, formulas, and persistence as tools. agent Headless WorkPaper agent handbook Pick MCP, direct TypeScript, service routes, or XLSX import with a required write-read-persist loop. challenge Agent workbook challenge Give another agent one input edit, one formula readback, one persisted restore, and a pass/fail proof object. openai OpenAI Responses WorkPaper tools Run npm run agent:openai-responses to dispatch function_call items and return computed readback. openai OpenAI Agents SDK WorkPaper tools Run npm run agent:openai-agents-sdk to verify Agent, tool(), and WorkPaper readback locally. adapters Agent framework spreadsheet tools Run npm run agent:ai-sdk-generate-text, npm run agent:ai-sdk-stream-text, or adapt tools for LangChain, Mastra, LlamaIndex.TS, LangGraph.js, CopilotKit, and Cloudflare Agents. mcp MCP spreadsheet tool server WorkPaper reads and writes over tools/list and tools/call. remote mcp Hosted MCP smoke endpoint Stateless Streamable HTTP endpoint for connector tests and tool discovery. clients MCP client setup Remote MCP smoke plus Claude, Cursor, VS Code, Cline, and Codex configs for the npm stdio server. mcpb Claude Desktop MCPB bundle Package the WorkPaper MCP server for local Claude Desktop installs.
bilig-workpaper-mcp stdio

    $ npm exec --package @bilig/workpaper@0.40.43 -- bilig-workpaper-mcp --workpaper ./pricing.workpaper.json --init-demo-workpaper --writable
    ok tools/list
    ok tools/call read_range
    ok tools/call set_cell_contents
    ok WorkPaper JSON persisted to file

    $ curl https://bilig.proompteng.ai/mcp -H 'accept: application/json, text/event-stream' -H 'mcp-protocol-version: 2025-11-25' ...
    ok stateless Streamable HTTP tools/list

Benchmark

## The benchmark is public. So is the caveat.

The checked JSON has bilig ahead on the aggregate mean and p95 scorecard, with holdouts visible. The worst p95 row is named beside the number.

workpaper-vs-hyperformula.json current run
comparable mean rows 94/100

94 of 100 comparable mean-latency rows are faster in the checked file. structural-move-rows is the current worst p95 row: `4.047x`. Browser UI rendering is not part of this benchmark.

Command
  `pnpm workpaper:bench:competitive:check`
Artifact
  `packages/benchmarks/baselines/workpaper-vs-hyperformula.json`
Worst p95
  structural-move-rows is the current worst p95 row: `4.047x`.
Out of scope
  UI rendering, Excel file compatibility, and workbook shapes this suite does not cover.

Read Benchmark notes Check Compatibility gaps Help Starter issues

Start here

## Pick the path that matches the job.

Try the package, put it behind a service route, expose it as an agent tool, or compare it with the spreadsheet stack you already use.

try it Try it in a blank Node project. Edit one input, restore the JSON document, and check the recalculated total. create Prepare a route-shaped WorkPaper starter. Run the public npm create package or the maintained API example and get a smoke-tested starter. service Put a WorkPaper behind a Node endpoint. Load state, write a cell, read the output, and save the document. agent Expose workbook reads and writes as tools. Let the tool write the cell and return the value the workbook calculated. challenge Give another agent a no-screenshot workbook eval. Require editedCell, before, after, afterRestore, persistedDocumentBytes, verified, and limitations. compare Check the alternatives before switching. Pick between browser grids, XLSX tooling, formula engines, and a WorkPaper runtime. limits Read the Excel gaps before importing real workbooks. Known missing behavior is listed before it surprises you. fixture Send a reduced workbook case. Turn a real blocker into a public test, example, corpus fixture, or compatibility note. clinic Bring a formula or XLSX blocker. Reduce stale caches, shared formulas, unsupported functions, and agent readback failures into public proof. report Generate a local clinic report. Run `bilig-formula-clinic` against a reduced workbook and paste the Markdown output into GitHub. contribute Take a starter issue that improves the examples. Start with code/test picks, example tasks, adapters, or focused docs coverage.

Reference

## Short paths for real integration work.

Open the install path, service recipe, agent adapter, or comparison page that matches the thing you are building.

### Run

- @bilig/workpaper npm package
- @bilig/xlsx-formula-recalc npm package
- @bilig/exceljs-formula-recalc npm package
- @bilig/headless npm package
- Node quickstart
- starter package status
- TypeScript examples
- workbook automation examples
- JSON records input
- invoice totals
- budget variance alerts
- fulfillment capacity plan
- quote approval threshold
- subscription MRR forecast

### Build

- Node service recipe
- server-side spreadsheet automation
- Google Sheets API boundary
- serverless WorkPaper API route
- Express, Fastify, Hono, Oak, Hapi, and AdonisJS adapters
- formula-backed persistence
- build a revenue model
- serverless API route example
- quote-approval-api smoke
- Postgres, Redis, and object storage adapters
- XLSX formula recalculation in Node
- curlable XLSX recalculation proof
- downloadable proof script

### Agents

- why agents need workbook APIs
- agent instructions
- agent skill manifest
- full LLM context pack
- Context7 indexed docs
- headless WorkPaper agent handbook
- agent workbook challenge
- agent tool-calling recipe
- OpenAI Agents SDK tool calls
- OpenAI Responses tool calls
- agent spreadsheet tool-call loop
- agent XLSX recalculation without LibreOffice
- Agent framework tools
- Mastra spreadsheet tool
- LlamaIndex.TS spreadsheet tool
- LangGraph.js ToolNode
- CopilotKit action
- Cloudflare Agents tool
- CrewAI spreadsheet tool
- MCP spreadsheet tool server
- spreadsheet MCP server comparison
- MCP directory status
- MCP client setup
- Claude Desktop MCPB bundle
- MCP Registry listing
- agent skill discovery index
- MCP workflow discussion

### Decide

- why use Bilig?
- screenshots vs workbook APIs
- Show HN formula workbook proof
- formula workbooks for Node services and agent tools
- AI spreadsheet agent tool for Node.js
- Node spreadsheet formula engine
- curlable XLSX recalculation proof
- downloadable proof script
- XLSX formula recalculation in Node.js
- agent XLSX formula recalculation without LibreOffice
- Excel file as a Node calculation engine
- stale XLSX formula cache in Node.js
- SheetJS formula result not updating in Node.js
- Microsoft Graph Excel recalculation in Node.js
- spreadsheet MCP server comparison
- xlsx-calc alternative for Node recalculation
- ExcelJS formula recalculation in Node.js
- ExcelJS shared formulas in Node.js
- xlsx-template formula recalculation in Node.js
- xlsx-populate formula results in Node.js
- headless spreadsheet engine for Node services and agents
- quote approval WorkPaper API proof
- starter package status
- production adoption checklist
- npm provenance and package trust
- evaluate Excel formulas in Node.js
- Google Sheets API boundary
- stale XLSX cache and Excel oracle checks
- JavaScript spreadsheet library for Node services
- SheetJS and ExcelJS alternatives
- HyperFormula alternative notes
- unsupported formula troubleshooting
- local benchmark walkthrough
- what the benchmark proves
- benchmark critique
- engine comparison
- compatibility limits
- formula bug clinic
- formula clinic report script
- submit a workbook fixture
- fixture discussion
- starter issues
- first-timers-only queue
- adoption blocker form
- GitHub discussions
- quickstart feedback
- workflow feedback
- serverless route feedback
- persistence adapter feedback
- security policy
- support policy

## Run it on one calculation you care about.

If the quickstart matches your workflow, star the repo. If it does not, name the blocker.

Install Star repo Watch releases Ask docs Name blocker Formula clinic Submit fixture GitHub