bilig

Headless WorkPaper runtime

Run workbook rules in Node.

Bilig gives services and agents a workbook API: write inputs, recalculate formulas, read outputs, and save JSON. Use the XLSX tools when saved files are still the contract.

No-clone check npm exec --yes --package @bilig/workpaper@latest -- bilig-evaluate --door workpaper-service --json Edits an input cell, recalculates a formula, saves JSON, restores it, and returns verified: true.

Start with @bilig/workpaper when your service or agent owns the workbook state. Use @bilig/headless for lower-level runtime imports and @bilig/xlsx-formula-recalc when a saved .xlsx file stays in the loop.

GitHub Actions summary WorkPaper run verified
Input
Inputs!B2 = 8
Formula
Summary!B2
Before
24000
After
38400
{
  "door": "workpaper-service",
  "editedCell": "Inputs!B2",
  "dependentCell": "Summary!B2",
  "persistedDocumentBytes": 999,
  "verified": true
}

Who needs this

Teams that keep business rules in workbook formulas.

Pricing, payout, approval, import, and forecast rules often start in cells. Bilig lets backend code run those cells directly instead of turning every rule into one-off service code.

first run Run the workbook model before you adopt it.

The evaluator writes one input, reads the formula output, saves the WorkPaper JSON, restores it, and checks the restored value. No account, no repo clone, no spreadsheet UI.

npm exec --yes --package @bilig/workpaper@latest -- \
  bilig-evaluate --door workpaper-service --json

Use @bilig/workpaper for starters, evaluators, and agent tools, @bilig/headless for lower-level runtime imports, and @bilig/xlsx-formula-recalc when XLSX is the boundary.

Market gap

Not another spreadsheet UI. Not just a formula engine.

File libraries move workbook bytes. Formula engines calculate formulas. Hosted spreadsheets need networked app state. Bilig targets the missing runtime layer for backend teams that need workbook-shaped logic under test.

01 / model

Keep the business rule readable.

Represent inputs, formulas, and outputs as sheets instead of burying every rule in custom service code.

02 / run

Let the service change the inputs.

Write values through a narrow API, recalculate dependent formulas, and read the cells that determine the decision.

03 / save

Persist the workbook state.

Save WorkPaper JSON for route handlers, queue jobs, tests, agent tools, and audit trails.

04 / bridge

Import or export XLSX when files matter.

Use the XLSX subpath and recalculation packages when the workflow still needs Excel-compatible files.

Quickstart

Run the WorkPaper loop first.

The fastest evaluation path is a real write, recalculate, read, save, and restore cycle from the published package.

No-clone command

terminal Node.js 22+
npm exec --yes --package @bilig/workpaper@latest -- \
  bilig-evaluate --door workpaper-service --json

Want a starter? Run npm create @bilig/workpaper@latest pricing-workpaper. Want the lower-level API? Install @bilig/headless. Need a saved workbook file? Use the XLSX bridge.

workpaper-service.json runtime readback
{
  "door": "workpaper-service",
  "editedCell": "Inputs!B2",
  "dependentCell": "Summary!B2",
  "before": 24000,
  "after": 38400,
  "afterRestore": 38400,
  "verified": true
}

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.

@bilig/headless service loop
const paper = WorkPaper.buildFromSheets(model)
paper.setCellContents(inputCell, 40)

const answer = paper.getCellDisplayValue(outputCell)
const saved = serializeWorkPaperDocument(exportWorkPaperDocument(paper))
const restored = createWorkPaperFromDocument(parseWorkPaperDocument(saved))

console.log({ answer, restored: restored.getCellDisplayValue(outputCell) })
ok formula readback
ok saved WorkPaper JSON
ok restored state

Benchmark

The benchmark artifact is public.

The checked scorecard has bilig ahead across HyperFormula, TrueCalc, Univer, xlsx-calc, IronCalc Rust. Coverage tiers and unsupported rows stay visible.

headless-performance-leadership-scorecard.json 5 engines
mean+p95 scorecard 100/100

100/100 comparable workloads win on both mean and p95 in the checked leadership scorecard. 100 of 100 comparable mean-latency rows are faster in the checked HyperFormula file. sheet-rename-dependencies is the current worst p95 row: 0.792x. Browser UI rendering is not part of this benchmark.

Command
pnpm headless:performance:check
Artifact
packages/benchmarks/baselines/headless-performance-leadership-scorecard.json
Providers
HyperFormula, TrueCalc, Univer, xlsx-calc, IronCalc Rust.
Worst p95
sheet-rename-dependencies is the current worst p95 row: 0.792x.
Out of scope
UI rendering, Excel file compatibility, and workbook shapes this suite does not cover.

Reference

Start narrow, then go deeper.

Choose by boundary. Use @bilig/workpaper when the service or agent owns workbook state, @bilig/headless for lower-level runtime imports, and @bilig/xlsx-formula-recalc for saved files.

Try it on the workbook rule your code already depends on.

Run one WorkPaper through Node: pricing, payouts, approval rules, import checks, or forecasts. If the model still has to live as XLSX, use the file bridge after the runtime path is clear.