I built Bilig for a specific mess I kept running into: a spreadsheet has the business logic, but the product needs the answer inside a Node service.
The usual options are awkward. Drive Excel somehow. Push the model into Google
Sheets and call an API. Reimplement the spreadsheet in application code. Or
read an .xlsx file and accidentally trust stale cached formula values.
Bilig is the smaller thing I wanted: keep the model as sheets and formulas, write inputs from code, read the calculated output, and save the workbook state as JSON so tests can replay it.
That is the whole pitch.
This starts from an empty directory and uses the latest published package.
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
curl -fsSLo quickstart.ts https://proompteng.github.io/bilig/npm-eval.ts
npx tsx quickstart.ts
The output should look like this:
{
"before": 24000,
"after": 38400,
"afterRestore": 38400,
"sheets": ["Inputs", "Summary"],
"verified": true
}
The line that matters is "verified": true. The script changes an input, reads
a formula result, serializes the workbook JSON, restores it, and gets the same
answer again. That last check is there because backend spreadsheet bugs often
show up only after the state crosses a boundary.
Bilig is a workbook-state API for Node. It is not mainly about evaluating
=A1+B1 in isolation. It is about this loop:
The API is built around a WorkPaper object because the workbook state is the
artifact I want under test. Screenshots are not enough, and cached XLSX formula
values are a common footgun.
The checked benchmark artifact currently says Bilig wins 100/100 comparable
workloads on mean latency against the HyperFormula-style baseline. It wins
100/100 on both mean and p95.
The worst p95 row is not hidden: sheet-rename-dependencies is the current worst p95 row at 0.792x.
Browser grid rendering is not part of this benchmark.
Read the benchmark note: what the WorkPaper benchmark proves.
Bilig is not Excel in Node. It does not run macros, preserve every workbook artifact, cover every Excel formula, do collaborative editing, or prove future p95 cases without adding them to the checked suite.
If you mainly need a mature broad formula engine, start with HyperFormula. If the problem is XLSX reading, writing, or styling, start with SheetJS or ExcelJS. If the product is a shared hosted spreadsheet, use Google Sheets.
Use @bilig/headless when your Node code can own the workbook state and you
care about formula readback, persistence, and restore checks.
I am looking for rejection reasons:
Open feedback here: https://github.com/proompteng/bilig/discussions/new?category=general.
If this is a problem you might come back to, star or bookmark the repo: https://github.com/proompteng/bilig/stargazers.
Suggested HN title:
Show HN: Bilig runs small formula workbooks in Node
Suggested short body:
I maintain Bilig. I built it for the annoying case where a spreadsheet owns a
small piece of business logic, but the product needs the answer in a Node
service.
The package gives you a WorkPaper object: write input cells, recalculate, read
output cells, serialize the workbook JSON, restore it, and test that the answer
is still the same after the boundary.
The quick npm check starts from an empty directory and does exactly that.
It is not Excel in Node. No macros, no full XLSX preservation claim, no full
Excel compatibility claim. If you need a mature broad formula engine,
HyperFormula is probably the first thing to test. If you need file manipulation,
start with SheetJS or ExcelJS.
The current benchmark artifact says 100/100 mean-latency wins on comparable
workloads, with the worst p95 row called out on the page.
I am looking for rejection reasons from people who have shipped this kind of
thing: missing formulas, XLSX cases, bad API shape, runtime pain, or the
benchmark that would make you trust or reject it faster.