bilig
Health Pass
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Community trust — 24 GitHub stars
Code Pass
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Fast headless spreadsheet engine for Node.js formulas, workbook automation, WorkPaper JSON, and agent workflows.
bilig
bilig runs spreadsheet formulas from Node.js. Build workbooks from arrays or
JSON records, edit cells, recalculate formulas, and save the document without
opening a spreadsheet UI.
Project site: https://proompteng.github.io/bilig/
Current Public Proof
- Live growth snapshot:
https://proompteng.github.io/bilig/community-growth-snapshot.html - Latest checked-in snapshot:
24GitHub stars,13,427npm downloads in the
last week,32opengood first issuetickets,7GitHub Discussions, and393recent repository views. - Benchmark evidence:
46/46comparable WorkPaper mean wins,
with the p95 caveat documented instead of hidden.
If the 90-second check below saves you a workbook-automation spike, star or
bookmark the repo after you see the verification output:
https://github.com/proompteng/bilig/stargazers.
Choose Your Path
- Evaluate in 90 seconds: run the npm-only
@bilig/headlessquickstart. - Decide if it fits your backend: read the
Node.js spreadsheet formula engine guide. - Compare spreadsheet engines: read the
SheetJS and ExcelJS comparison,
HyperFormula comparison,
engine comparison, and
benchmark explainer. - Build a Node workflow: start from the
five runnable workbook automation examples,
runnable WorkPaper example,
JSON records input example,
invoice totals example,
budget variance example,
fulfillment capacity example,
quote approval example,
subscription MRR example,
serverless API route example,
Node service recipe, or
serverless route walkthrough. - Wire a coding-agent tool: use the
Vercel AI SDK / LangChain spreadsheet tool guide,
MCP spreadsheet tool server guide,
agent tool-calling recipe, or
run the
Vercel AI SDK / LangChain adapter example
and MCP tool server example. - Contribute a small patch: pick a scoped
good first issue. - Ask a question or share a workflow: use
GitHub Discussions for
Q&A, ideas, and show-and-tell posts. - Report an Excel compatibility gap: use the issue templates and link the
smallest workbook, formula, or fixture that reproduces the mismatch. - Follow the project: star the repo as a bookmark:
https://github.com/proompteng/bilig/stargazers.
Contributor and security docs:CONTRIBUTING.md and SECURITY.md.
Try @bilig/headless in 90 seconds
The fastest evaluation path uses the published npm package only. It builds a
formula-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
Create eval.mjs:
import {
WorkPaper,
createWorkPaperFromDocument,
exportWorkPaperDocument,
parseWorkPaperDocument,
serializeWorkPaperDocument,
} from '@bilig/headless'
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)'],
],
})
const numberValue = (cell) => {
if (typeof cell === 'object' && cell !== null && typeof cell.value === 'number') {
return cell.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:
node eval.mjs
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 runnable
JSON 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, formula
parser/compiler, React workbook reconciler, reusable grid shell, binary sync
protocol, agent API, browser/server persistence layers, and a conservative
AssemblyScript/WASM fast path for formula families that have proven parity.
The long-term target is a spreadsheet platform that can be edited by people or
agents, restored locally, synchronized through ordered mutation streams, and
benchmarked 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/export
live below the React shell. - Local-first by design: browser sessions restore from local state, preserve
replica 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 state
without screen scraping. - Performance tied to proof: formula acceleration and WorkPaper benchmark
work are backed by parity fixtures, differential checks, counters, and CI
gates 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 through
apps/weband@bilig/grid. - Author deterministic workbooks with React components through
@bilig/renderer. - Exercise the product runtime through the
apps/biligmonolith, which serves
the built web shell and backend APIs. - Run WorkPaper and browser performance contracts from
packages/benchmarks,scripts/, ande2e/tests. - Build the AssemblyScript WASM kernel with
pnpm wasm:build.
Current Status
bilig is early, serious infrastructure. The architecture is broad and the
correctness 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 documented
WorkPaper API directly. The package README is the contract for install, API
usage, persistence, validation, supported scope, and agent workflow:
packages/headless/README.md.
For the shortest public method map, start with the
WorkPaper 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.mjs with the quickstart below, then run node eval.mjs. The
example builds a formula-backed workbook, edits source data, serializes the
document, restores it, and verifies that the recalculated value survives the
round trip.
For a runnable external-consumer example, start with
examples/headless-workpaper. The repository smoke
test 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, applies
one 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 reads
formula-backed summary values.
For JSON service/API payloads, the runnable example includesnpm run json-records. It
maps an array of opportunity records into WorkPaper.buildFromSheets(), adds
formula-backed summary cells, and validates exact computed output before
printing JSON.
For billing-style service payloads, the runnable example includesnpm run invoice-totals. It
calculates line-item totals, subtotal, tax, and grand total formulas, then
validates 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, and
flags 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 prints
starting 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, and
an 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, calculates
required 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 structured
diagnostics so services and agents can reject or normalize unsupported inputs.
That example also includes npm run agent:verify, a small agent writeback demo
that records the exact assumption cells changed, verifies dependent formula
readback, persists the workbook, restores it, and proves the formulas and values
survived 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, formula
contracts, persistence proof, and round-trip verification.
For Vercel AI SDK and LangChain-shaped wrappers, runnpm run agent:framework-adapters. The example keeps the same validated
WorkPaper read/write functions and exposes thin framework adapter shapes
without adding either framework as a dependency.
For an MCP-style shape, run npm run agent:mcp-tools. It returns a
dependency-free tools/list response, a tools/call read, and a verified
input edit with structured computed readback. Run npm run agent:mcp-stdio
when you want the same tools over newline-delimited JSON-RPC stdio.
Quickstart:
import {
WorkPaper,
createWorkPaperFromDocument,
exportWorkPaperDocument,
parseWorkPaperDocument,
serializeWorkPaperDocument,
} from '@bilig/headless'
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 },
)
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, col) => ({
sheet: summary,
row,
col,
})
const before = 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 = 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 intosrc/ordist/unless the task is to change the package itself. - Addresses are zero-based
{ sheet, row, col }; resolve sheet ids withgetSheetId(). - Use
exportWorkPaperDocument()andcreateWorkPaperFromDocument()for
persistence 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, andpnpm run cibefore publishing
or claiming production readiness.
For workflow feedback from people building Node services or agent tools, use
the 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 spreadsheet
screenshots.
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, and
persistence into a small tool surface.
For the persistence-focused follow-up article and runnable example, seedocs/persisting-formula-backed-workpaper-documents-in-node.md
andexamples/headless-workpaper/persistence-roundtrip.mjs.
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 turning
the 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 smoke
benchmark, 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, and
JSpreadsheet Formula Pro, seedocs/headless-spreadsheet-engine-comparison.md.
For a runnable revenue-model walkthrough, seedocs/building-a-revenue-model-with-headless-workpaper.md
andexamples/headless-workpaper/revenue-scenarios.mjs.
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 treating
the 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 GROUPBY
output, seedocs/formula-edge-groupby-spill-fixture.md.
For the published DEV article, see
https://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:3000for the monolith web shell with/v2,/api/zero/v2, and/zerohttp://localhost:4321/healthzfor the monolith app runtimehttp://localhost:4848/keepalivefor Zero cachepostgresql://bilig:bilig@localhost:5432/biligfor 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 narrowest
targeted 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 compares
bilig's spreadsheet runtime against HyperFormula-style workloads and keeps the
important 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 WorkPaper46/46mean wins on
scorecard-eligible comparable workloads:38/38public and8/8holdout.docs/assets/workpaper-benchmark-card.pngis the shareable chart for the
current scorecard. It is generated from the checked-in artifact withpnpm docs:benchmark-card:generate.docs/headless-workpaper-benchmark-evidence.mdexplains what is measured,
what is excluded, and why this is a mean-win claim rather than a blanket p95
guarantee.
Start here:
docs/workpaper-engine-leadership-program.mddocs/headless-workpaper-benchmark-evidence.mddocs/what-workpaper-benchmark-proves.mddocs/local-workpaper-benchmark-walkthrough.mddocs/workpaper-oracle-sota-performance-design-2026-04-21.mddocs/workpaper-oracle-validated-performance-design-2026-04-26.mddocs/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.mddocs/public-api.mddocs/formula-language.mddocs/agent-api.mddocs/local-first-realtime-loop.mddocs/binary-protocol.mddocs/wasm-runtime-contract.mddocs/testing-and-benchmarks.md
Contributing
Read CONTRIBUTING.md before opening a PR. If this is your
first patch, start with the
new contributor guide and then claim a scoped
starter 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 are
scoped around small runnable examples with explicit acceptance commands, so a
first contribution can improve the public WorkPaper evaluation path without
understanding the whole engine.
If this is your first contribution to bilig, start with thefirst-timers-only
filter.
Please keep changes small, tested, and tied to the package that owns the
behavior.
CI
Forgejo Actions is the primary CI surface for this repo via.forgejo/workflows/forgejo-ci.yml. GitHub Actions mirrors the verification
contract in .github/workflows/ci.yml.
The strict gate includes frozen lockfile install, full pnpm run ci, artifact
budget checks, browser smoke, and tracked-file cleanliness checks.
License
MIT.
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found