Use @bilig/headless when a Node.js service needs spreadsheet formulas as part
of its own runtime. The useful case is not “make a prettier spreadsheet.” It is
“accept inputs, update workbook state, recalculate formulas, persist the
document, and return values that were actually read back from the engine.”
That shows up in ordinary backend work:
If you only need to write an XLSX file for Excel to open later, use an XLSX
library. If you need maximum Excel-function coverage today, evaluate
HyperFormula first. If you need a small TypeScript WorkPaper object that a Node
process can mutate, verify, and save as JSON, @bilig/headless is the slice to
try.
@bilig/headless gives the service a WorkPaper object. A WorkPaper is a
programmatic workbook with sheets, cell addresses, formulas, computed values,
structural edits, and persistence helpers.
The important boundary is readback. Do not trust that a service “wrote the formula” just because a string was assigned. Read the calculated cell value through the WorkPaper API, serialize the document, restore it, and read the same value again. That is the path the package is built around.
Run this from an empty directory:
mkdir bilig-formula-engine-eval
cd bilig-formula-engine-eval
npm init -y
npm pkg set type=module
npm install @bilig/headless
npm install -D tsx typescript @types/node
cat > formula-engine-smoke.ts <<'EOF'
import { WorkPaper } from '@bilig/headless'
type NumericCell = {
value: number
}
function readNumber(cell: unknown, label: string): number {
if (typeof cell === 'object' && cell !== null && typeof (cell as NumericCell).value === 'number') {
return (cell as NumericCell).value
}
throw new Error(`Expected ${label} to be numeric, got ${JSON.stringify(cell)}`)
}
const workbook = WorkPaper.buildFromSheets({
Plan: [
['Metric', 'Value'],
['Customers', 80],
['Price', 49],
['Discount', 0.08],
],
Summary: [
['Metric', 'Value'],
['Net revenue', '=Plan!B2*Plan!B3*(1-Plan!B4)'],
],
})
const sheet = workbook.getSheetId('Summary')
if (sheet === undefined) {
throw new Error('Summary sheet was not created')
}
const netRevenue = readNumber(workbook.getCellValue({ sheet, row: 1, col: 1 }), 'net revenue')
if (netRevenue !== 3606.4) {
throw new Error(`Unexpected formula readback: ${netRevenue}`)
}
console.log({ netRevenue, verified: true })
EOF
npx tsx formula-engine-smoke.ts
Expected output:
{ "netRevenue": 3606.4, "verified": true }
That tiny check proves three things at once: multi-sheet workbook creation, formula evaluation, and computed readback from Node.
Start here when the service needs a workbook model, not just isolated formula functions.
| Need | Why @bilig/headless helps |
|---|---|
| Put spreadsheet formulas behind an API | The service can build a WorkPaper, edit input cells, and return computed cells. |
| Let an agent edit a workbook safely | The agent can report exact changed cells and post-write readback instead of only narrating intent. |
| Persist formula-backed state | Export the WorkPaper document, store JSON, restore it later, and verify formulas still calculate. |
| Keep examples runnable | The repo includes invoice, budget variance, subscription MRR, quote approval, and capacity examples. |
Use a different tool when the job is outside this package’s current shape:
bilig expecting a finished Excel clone. The compatibility
boundaries are public because the project is still early.If the smoke test matches your use case, run the maintained example next:
git clone https://github.com/proompteng/bilig.git
cd bilig/examples/headless-workpaper
npm install
npm start
npm run agent:verify
Then inspect the focused examples:
If this package saves you a workbook automation spike, star the repository so the project is easier for the next backend developer to find: https://github.com/proompteng/bilig/stargazers.
If it almost matches but a gap blocks adoption, use the adoption blocker form: https://github.com/proompteng/bilig/discussions/new?category=general.