proompteng

bilig

Community proompteng
Updated

Fast headless spreadsheet engine for Node.js formulas, workbook automation, WorkPaper JSON, and agent workflows.

bilig

CIGitHub Repo starsnpm: @bilig/headlessnpm weekly downloadsLicense: MIT

bilig is a headless workbook runtime for TypeScript. Use it when thespreadsheet is the model, not the UI: pricing rules, finance checks, agenttools, import jobs, queue workers, and serverless routes that need formulas torecalculate the same way every run.

Project site: https://proompteng.github.io/bilig/

When It Fits

Good fit Use something else when
A Node service needs workbook formulas, named sheets, edits, and readback You only need a visual grid component
An agent tool must write an input cell and return the calculated result You need desktop Excel automation or Office macros
A backend job needs to save and restore formula-backed workbook state Your workflow starts and ends with manual XLSX editing
Tests need a deterministic workbook model instead of screenshots You want a general-purpose table library with no spreadsheet formula model

Current Public Proof

  • Live growth snapshot:https://proompteng.github.io/bilig/community-growth-snapshot.html
  • Latest checked-in snapshot: 24 GitHub stars, 10 forks, 15,592 npm downloads in thelast week, 23,240 npm downloads in the last 30 days, 55 opengood first issue tickets, 8 GitHub Discussions, and 393 recentrepository views.
  • Benchmark evidence:46/46 comparable WorkPaper mean wins,with the p95 caveat documented instead of hidden.
  • MCP discovery: listed in theofficial MCP Registryand on .

If the 90-second check below saves you a workbook automation spike, star therepo so you can find it again:https://github.com/proompteng/bilig/stargazers.

Start Here

Job Start with
Prove the npm package @bilig/headless in 90 seconds and the npm-only smoke test page
Build a Node workflow five runnable workbook automation examples, evaluate Excel formulas in Node.js, Node spreadsheet formula engine guide, and the Node service recipe
Wire an agent or MCP tool agent tool-calling recipe and MCP spreadsheet tool server guide
Compare alternatives headless engine comparison, HyperFormula comparison
Contribute starter issues, GitHub Discussions, and CONTRIBUTING.md

Useful direct paths:

  • Node workflow examples:invoice totals,budget variance,fulfillment capacity,quote approval,subscription MRR, andserverless API route.
  • Agent and MCP adapters:Vercel AI SDK / LangChain guide,framework adapters,MCP tool server shape, andMCP server guide. Runnpm run agent:framework-adapters, npm run agent:mcp-tools,npm run agent:mcp-stdio, ornpm exec --package @bilig/headless -- bilig-workpaper-mcp.
  • SEO comparison pages:evaluate Excel formulas in Node.js,Node spreadsheet formula engine,SheetJS and ExcelJS alternative,headless engine comparison,and HyperFormula comparison.

The published MCP Registry entry isio.github.proompteng/bilig-workpaper.

Try @bilig/headless in 90 seconds

The fastest evaluation path uses the published npm package only. It builds aformula-backed workbook, applies an edit, persists the document, restores it,and throws if formula readback does not survive the round trip.

mkdir bilig-headless-eval
cd bilig-headless-eval
npm init -y
npm pkg set type=module
npm install @bilig/headless
npm install -D tsx typescript @types/node

Create eval.ts:

import {
  WorkPaper,
  createWorkPaperFromDocument,
  exportWorkPaperDocument,
  parseWorkPaperDocument,
  serializeWorkPaperDocument,
} from '@bilig/headless'

type NumericCell = {
  value: number
}

const workbook = WorkPaper.buildFromSheets({
  Revenue: [
    ['Region', 'Customers', 'ARPA', 'Revenue'],
    ['West', 20, 1200, '=B2*C2'],
    ['East', 30, 250, '=B3*C3'],
    ['Central', 18, 300, '=B4*C4'],
  ],
  Summary: [
    ['Metric', 'Value'],
    ['Total revenue', '=SUM(Revenue!D2:D4)'],
  ],
})

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

const revenue = workbook.getSheetId('Revenue')
const summary = workbook.getSheetId('Summary')
if (revenue === undefined || summary === undefined) {
  throw new Error('Workbook sheets were not created')
}

const before = numberValue(workbook.getCellValue({ sheet: summary, row: 1, col: 1 }))
workbook.setCellContents({ sheet: revenue, row: 1, col: 1 }, 32)

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

const after = numberValue(restored.getCellValue({ sheet: restoredSummary, row: 1, col: 1 }))
const verified = before === 36900 && after === 51300 && saved.length > 0
if (!verified) {
  throw new Error(`Unexpected formula readback: ${JSON.stringify({ before, after, bytes: saved.length })}`)
}

console.log({ before, after, sheets: restored.getSheetNames(), bytes: saved.length, verified })

Run it:

npx tsx eval.ts

Expected output:

{
  "before": 36900,
  "after": 51300,
  "sheets": ["Revenue", "Summary"],
  "bytes": 1064,
  "verified": true
}

The maintained repository example adds agent-style writeback verification:

git clone https://github.com/proompteng/bilig.git
cd bilig/examples/headless-workpaper
npm install
npm start
npm run agent:tool-call
npm run agent:framework-adapters
npm run agent:verify

Expected proof from npm run agent:tool-call includes:

{
  "toolCall": { "toolName": "setInputCell" },
  "toolResult": {
    "editedCell": "Inputs!B3",
    "before": { "expectedArr": 60000, "targetGap": -34000 },
    "after": { "expectedArr": 96000, "targetGap": 5600 },
    "verified": {
      "formulasPersisted": true,
      "restoredMatchesAfter": true,
      "expectedArrImproved": true,
      "targetGapClosed": true
    }
  }
}

Expected proof from npm run agent:verify includes:

{
  "after": {
    "customers": 65,
    "grossMrr": 15600,
    "expansionMrr": 18720,
    "annualizedArr": 224640,
    "arrTargetDelta": 74640
  },
  "verified": {
    "formulasUnchanged": true,
    "formulasPersisted": true,
    "restoredMatchesAfter": true
  }
}

The serverless route example gives HTTP and agent-tool evaluators a runnableJSON boundary:

git clone https://github.com/proompteng/bilig.git
cd bilig/examples/serverless-workpaper-api
npm install
npm run smoke

Expected proof from npm run smoke includes:

{
  "edit": {
    "records": 4,
    "after": {
      "totalRevenue": 48600,
      "westCustomers": 20,
      "largestDeal": 24000
    },
    "checks": {
      "totalRevenueChanged": true,
      "formulasPersisted": true
    }
  },
  "verified": true
}

It is not a table widget. The repo contains a real workbook engine, formulaparser/compiler, React workbook reconciler, reusable grid shell, binary syncprotocol, agent API, browser/server persistence layers, and a conservativeAssemblyScript/WASM fast path for formula families that have proven parity.

The long-term target is a spreadsheet platform that can be edited by people oragents, restored locally, synchronized through ordered mutation streams, andbenchmarked against serious spreadsheet-engine workloads.

Why Watch This Repo

  • Spreadsheet engine, not just UI: workbook mutation, formulas, snapshots,history, selections, dependency inspection, replica hooks, and import/exportlive below the React shell.
  • Local-first by design: browser sessions restore from local state, preservereplica snapshots, and keep outbound edits as replayable mutation batches.
  • Agent-addressable workbooks: the engine exposes stable request, response,event, and subscription shapes so agents can operate on spreadsheet statewithout screen scraping.
  • Performance tied to proof: formula acceleration and WorkPaper benchmarkwork are backed by parity fixtures, differential checks, counters, and CIgates instead of benchmark-only rewrites.
  • Reusable package boundaries: formula, core, grid, renderer, transport,protocol, storage, benchmark, and runtime concerns are split into packages.

What Works Today

  • Create, mutate, snapshot, restore, undo, redo, and inspect workbooks through@bilig/core.
  • Parse, bind, compile, and evaluate spreadsheet formulas through@bilig/formula, with fixture-driven parity checks.
  • Render and navigate a virtualized browser spreadsheet shell throughapps/web and @bilig/grid.
  • Author deterministic workbooks with React components through@bilig/renderer.
  • Exercise the product runtime through the apps/bilig monolith, which servesthe built web shell and backend APIs.
  • Run WorkPaper and browser performance contracts from packages/benchmarks,scripts/, and e2e/tests.
  • Build the AssemblyScript WASM kernel with pnpm wasm:build.

Current Status

bilig is early, serious infrastructure. The architecture is broad and thecorrectness bar is intentionally high, but it is not a finished Excel clone.

Known open areas include:

  • full Excel formula parity
  • defined names, tables, structured references, and deeper dynamic-array support
  • worker-first browser runtime as the default boot path
  • final durable multiplayer sync backend
  • typed binary agent frames end to end
  • more public package release hardening

Headless WorkPaper In Five Minutes

Start here when you want to use the spreadsheet engine from Codex, Claude Code,a service, or a Node script without opening the browser UI.

@bilig/headless is production-ready for applications that call the documentedWorkPaper API directly. The package README is the contract for install, APIusage, persistence, validation, supported scope, and agent workflow:packages/headless/README.md.For the shortest public method map, start with theWorkPaper read/write cheat sheet.

Install from npm:

pnpm add @bilig/headless

Try the package without cloning the monorepo:

mkdir bilig-headless-eval
cd bilig-headless-eval
npm init -y
npm pkg set type=module
npm install @bilig/headless

Create eval.ts with the quickstart below, then run npx tsx eval.ts. Theexample builds a formula-backed workbook, edits source data, serializes thedocument, restores it, and verifies that the recalculated value survives theround trip.

For a runnable external-consumer example, start withexamples/headless-workpaper. The repository smoketest executes that same example against packed local runtime packages withpnpm workpaper:smoke:external.

For backend adoption, seedocs/node-service-workpaper-recipe.md.It shows a minimal Node service boundary that reads computed summaries, appliesone controlled edit, and persists the WorkPaper document.

For tabular service payloads, seedocs/csv-shaped-workpaper-input-recipe.md.It normalizes a small CSV-shaped fixture into a WorkPaper workbook and readsformula-backed summary values.

For JSON service/API payloads, the runnable example includesnpm run json-records. Itmaps an array of opportunity records into WorkPaper.buildFromSheets(), addsformula-backed summary cells, and validates exact computed output beforeprinting JSON.

For billing-style service payloads, the runnable example includesnpm run invoice-totals. Itcalculates line-item totals, subtotal, tax, and grand total formulas, thenvalidates exact computed and serialized formula readback.

For reporting and finance automation, the runnable example includesnpm run budget-variance.It compares budget and actual rows, calculates dollar and percent variance, andflags rows that need review with a formula-backed alert.

For subscription revenue forecasting, the runnable example includesnpm run subscription-mrr.It models starting customers, churn, expansion, and new customers, then printsstarting MRR, ending MRR, net expansion MRR, and verified formula readback.

For sales-ops quote workflows, the runnable example includesnpm run quote-approval.It calculates list total, discount amount, quote total, max line discount, andan approval flag from formula-backed quote rows.

For operations planning, the runnable example includesnpm run fulfillment-capacity.It compares forecast order volume with available labor hours, calculatesrequired hours, capacity gap, short days, and a formula-backed status.

For formula errors, seedocs/unsupported-formula-troubleshooting-recipe.md.It shows how to read #VALUE!/#NAME? display text together with structureddiagnostics so services and agents can reject or normalize unsupported inputs.

That example also includes npm run agent:verify, a small agent writeback demothat records the exact assumption cells changed, verifies dependent formulareadback, persists the workbook, restores it, and proves the formulas and valuessurvived the round trip.

For a tool-calling shape closer to agent SDKs, run npm run agent:tool-call.It returns a compact tool call, before/after computed values, formulacontracts, persistence proof, and round-trip verification.

For Vercel AI SDK and LangChain-shaped wrappers, runnpm run agent:framework-adapters. The example keeps the same validatedWorkPaper read/write functions and exposes thin framework adapter shapeswithout adding either framework as a dependency.

For an MCP-style shape, run npm run agent:mcp-tools. It returns adependency-free tools/list response, a tools/call read, and a verifiedinput edit with structured computed readback. Run npm run agent:mcp-stdiowhen you want the same tools over newline-delimited JSON-RPC stdio.The package-level stdio binary is bilig-workpaper-mcp, runnable withnpm exec --package @bilig/headless -- bilig-workpaper-mcp.It is published in the official MCP Registry asio.github.proompteng/bilig-workpaper:https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.proompteng%2Fbilig-workpaper.

Quickstart:

import {
  WorkPaper,
  createWorkPaperFromDocument,
  exportWorkPaperDocument,
  parseWorkPaperDocument,
  serializeWorkPaperDocument,
  type WorkPaperCellAddress,
} from '@bilig/headless'

type NumericCell = {
  value: number
}

const workbook = WorkPaper.buildFromSheets(
  {
    Revenue: [
      ['Region', 'Customers', 'ARPA', 'Revenue'],
      ['West', 20, 1200, '=B2*C2'],
      ['East', 30, 250, '=B3*C3'],
      ['Central', 18, 300, '=B4*C4'],
    ],
    Summary: [
      ['Metric', 'Value'],
      ['Total revenue', '=SUM(Revenue!D2:D4)'],
    ],
  },
  { maxRows: 1_000, maxColumns: 100, useColumnIndex: true },
)

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

const revenue = workbook.getSheetId('Revenue')
const summary = workbook.getSheetId('Summary')
if (revenue === undefined || summary === undefined) {
  throw new Error('Workbook sheets were not created')
}

const at = (row: number, col: number): WorkPaperCellAddress => ({
  sheet: summary,
  row,
  col,
})

const before = numberValue(workbook.getCellValue(at(1, 1)))
workbook.setCellContents({ sheet: revenue, row: 1, col: 1 }, 32)

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

const after = numberValue(
  restored.getCellValue({
    sheet: restoredSummary,
    row: 1,
    col: 1,
  }),
)

console.log({ before, after, sheets: restored.getSheetNames(), bytes: saved.length })

Rules for agents:

  • Use public package exports from @bilig/headless; do not reach into src/ ordist/ unless the task is to change the package itself.
  • Addresses are zero-based { sheet, row, col }; resolve sheet ids withgetSheetId().
  • Use exportWorkPaperDocument() and createWorkPaperFromDocument() forpersistence round trips.
  • Add tests before changing config rebuilds, range bounds, formulas,persistence, or structural edits.
  • Run focused headless tests first, then pnpm publish:runtime:check,pnpm workpaper:bench:competitive:check, and pnpm run ci before publishingor claiming production readiness.

For workflow feedback from people building Node services or agent tools, usethe GitHub discussion:https://github.com/proompteng/bilig/discussions/157.

For the five runnable service-workflow examples as one shareable thread, see:https://github.com/proompteng/bilig/discussions/213.

For the search-friendly version with commands and current output snippets, seedocs/workbook-automation-examples-node.md.

For the first technical adoption article, seedocs/why-agents-need-workbook-apis.md.It explains why agents should operate on workbook APIs instead of spreadsheetscreenshots.

For a concrete framework-neutral agent tool loop, seedocs/agent-workpaper-tool-calling-recipe.md.It wraps WorkPaper reads, validated writes, computed before/after checks, andpersistence into a small tool surface.

For the persistence-focused follow-up article and runnable example, seedocs/persisting-formula-backed-workpaper-documents-in-node.mdandexamples/headless-workpaper/persistence-roundtrip.ts.

For the benchmark-focused explainer, seedocs/what-workpaper-benchmark-proves.md.It states the 46/46 mean-win claim and the known p95 caveat without turningthe benchmark into a blanket performance claim.

For a local benchmark command walkthrough, seedocs/local-workpaper-benchmark-walkthrough.md.It shows how to verify the checked-in artifact, run a reduced local smokebenchmark, and compare benchmark diffs.

For a concise HyperFormula comparison and evaluation path, seedocs/hyperformula-alternative-headless-workpaper.md.

For a broader headless spreadsheet-engine comparison across @bilig/headless,HyperFormula, IronCalc, ExcelJS, Formula.js, Hucre, Formualizer, andJSpreadsheet Formula Pro, seedocs/headless-spreadsheet-engine-comparison.md.

For a runnable revenue-model walkthrough, seedocs/building-a-revenue-model-with-headless-workpaper.mdandexamples/headless-workpaper/revenue-scenarios.ts.

For the current Excel-compatibility boundaries, seedocs/where-bilig-is-not-excel-compatible-yet.md.It names the macro, formula, XLSX corpus, and UI-claim gaps without treatingthe project as a complete Excel clone.

For a short guide to interpreting XLSX cached-result corpus reports, seedocs/xlsx-corpus-verifier-walkthrough.md.

For a formula-edge fixture walkthrough covering the exact-match XLOOKUP path,seedocs/formula-edge-xlookup-exact-fixture.md.

For a formula-edge fixture walkthrough covering paired-criteria SUMIFS, seedocs/formula-edge-sumifs-paired-criteria-fixture.md.

For a formula-edge fixture walkthrough covering grouped dynamic-array GROUPBYoutput, seedocs/formula-edge-groupby-spill-fixture.md.

For the published DEV article, seehttps://dev.to/gregkonush/why-agents-need-workbook-apis-instead-of-spreadsheet-screenshots-3d61.The source mirror with front matter isdocs/dev-to-workbook-apis-post.md.

Quickstart

Use Node 24+, Bun, and [email protected].

pnpm install
pnpm wasm:build
pnpm typecheck
pnpm test
pnpm dev

The default dev command runs the local web shell and monolith together.

Useful alternatives:

pnpm dev:web
pnpm dev:web-local
pnpm dev:sync

Local Docker Compose

docker compose up --build

This brings up:

  • http://localhost:3000 for the monolith web shell with /v2,/api/zero/v2, and /zero
  • http://localhost:4321/healthz for the monolith app runtime
  • http://localhost:4848/keepalive for Zero cache
  • postgresql://bilig:bilig@localhost:5432/bilig for Postgres

To reset local state:

docker compose down -v

Package Map

Path Role
apps/web Vite/React browser source compiled into the monolith
apps/bilig Fullstack monolith runtime, API surface, and static asset server
packages/protocol Shared enums, opcodes, constants, and protocol types
packages/formula A1 addressing, lexer, parser, binder, compiler, JS evaluator
packages/core Workbook engine, scheduler, snapshots, selectors, sync ownership, WASM facade
packages/headless Headless WorkPaper runtime surfaces
packages/zero-sync Zero schema, workbook queries, projection, and event payload helpers
packages/binary-protocol Wire format for sync frames
packages/agent-api Agent request, response, event, and framing model
packages/worker-transport Engine host/client bridge for worker execution
packages/renderer Custom workbook reconciler and workbook DSL
packages/grid Reusable React spreadsheet UI components and hooks
packages/wasm-kernel AssemblyScript/WASM compute fast path
packages/storage-browser Browser-side persistence
packages/storage-server Server-side storage integration points
packages/excel-fixtures Checked-in formula parity fixtures
packages/benchmarks Benchmark harness and performance contracts

Verification

The repo has a strict local preflight. For small changes, run the narrowesttargeted command first; before publishing, use the full gate.

pnpm lint
pnpm typecheck
pnpm test
pnpm test:browser
pnpm bench:smoke
pnpm run ci

Generated sources are checked in and enforced:

pnpm protocol:check
pnpm formula-inventory:check
pnpm workspace-resolution:check
pnpm workpaper:bench:competitive:check

Performance Work

The WorkPaper track is the repo's performance-leadership program. It comparesbilig's spreadsheet runtime against HyperFormula-style workloads and keeps theimportant claims tied to benchmark artifacts, counters, and docs.

Current public evidence:

  • packages/benchmarks/baselines/workpaper-vs-hyperformula.json, generated at2026-05-08T15:00:27.603Z, records WorkPaper 46/46 mean wins onscorecard-eligible comparable workloads: 38/38 public and 8/8 holdout.
  • docs/assets/workpaper-benchmark-card.png is the shareable chart for thecurrent scorecard. It is generated from the checked-in artifact withpnpm docs:benchmark-card:generate.
  • docs/headless-workpaper-benchmark-evidence.md explains what is measured,what is excluded, and why this is a mean-win claim rather than a blanket p95guarantee.

Start here:

  • docs/workpaper-engine-leadership-program.md
  • docs/headless-workpaper-benchmark-evidence.md
  • docs/what-workpaper-benchmark-proves.md
  • docs/local-workpaper-benchmark-walkthrough.md
  • docs/workpaper-oracle-sota-performance-design-2026-04-21.md
  • docs/workpaper-oracle-validated-performance-design-2026-04-26.md
  • docs/workpaper-oracle-benchmark-expansion-performance-plan-2026-04-28.md

Run the competitive benchmark with:

pnpm bench:workpaper:competitive

Architecture Docs

Good entry points:

  • docs/architecture.md
  • docs/public-api.md
  • docs/formula-language.md
  • docs/agent-api.md
  • docs/local-first-realtime-loop.md
  • docs/binary-protocol.md
  • docs/wasm-runtime-contract.md
  • docs/testing-and-benchmarks.md

Contributing

Read CONTRIBUTING.md before opening a PR. If this is yourfirst patch, start with thenew contributor guide and then claim a scopedstarter issue. The highest-value contributions are usually:

  • formula parity fixtures and semantic tests
  • WorkPaper benchmark scenarios with clear expected behavior
  • focused engine correctness fixes
  • grid accessibility and keyboard-behavior improvements
  • docs that turn existing architecture notes into runnable examples

The shortest public on-ramp is thestarter issues queue. Current starter issues arescoped around small runnable examples with explicit acceptance commands, so afirst contribution can improve the public WorkPaper evaluation path withoutunderstanding the whole engine.If this is your first contribution to bilig, start with thefirst-timers-onlyfilter.

Please keep changes small, tested, and tied to the package that owns thebehavior.

CI

Forgejo Actions is the primary CI surface for this repo via.forgejo/workflows/forgejo-ci.yml. GitHub Actions mirrors the verificationcontract in .github/workflows/ci.yml.

The strict gate includes frozen lockfile install, full pnpm run ci, artifactbudget checks, browser smoke, and tracked-file cleanliness checks.

License

MIT.

MCP Server ยท Populars

MCP Server ยท New