SheetJS formula result not updating in Node.js
May 26, 2026 ยท View on GitHub
This page is for the exact SheetJS / xlsx failure mode where a Node service
loads or creates an .xlsx, changes an input cell, then reads a formula cell
and still sees the old cached result.
Short answer: keep SheetJS for file I/O, but add a recalculation step before you trust formula readback.
Why the value is stale
XLSX formula cells can carry both formula text and a cached value. SheetJS cell
objects expose formula text and cell values, but the Community Edition path is
file-centric. If your process changes Inputs!B2, the cached value in
Summary!B7 does not become fresh just because the source cell changed.
That is fine when Excel, LibreOffice, or another spreadsheet application will open the workbook later and calculate it. It is not fine when a backend route, queue worker, or test must make a decision from the computed value in the same Node process.
Use a narrow recalculation bridge
If your app already has XLSX bytes from SheetJS, use the SheetJS-named recalculation bridge at the boundary. It keeps SheetJS responsible for file I/O and adds only the missing recalculation/readback step:
npm install @bilig/sheetjs-formula-recalc
One-off proof:
npx --package @bilig/sheetjs-formula-recalc sheetjs-recalc --demo --json
Exact reproduction for the high-view Stack Overflow question:
git clone https://github.com/proompteng/bilig.git
cd bilig
npm --prefix examples/recalc-bridge-workflows install
npm --prefix examples/recalc-bridge-workflows run so:sheetjs-63085785
That script mirrors the small case from
How to recalculate all formulas in excel file through Javascript?:
A1 changes from 1 to 3, SheetJS still has the stale cached C1 = 3,
then @bilig/sheetjs-formula-recalc verifies C1 = 5.
For a real workbook:
npx --package @bilig/sheetjs-formula-recalc sheetjs-recalc pricing.xlsx \
--set Inputs!B2=48 \
--set Inputs!B3=1500 \
--read Summary!B7 \
--out pricing.recalculated.xlsx \
--json
The command writes an updated workbook and prints the values read after recalculation.
Minimal API path
import { readFile, writeFile } from 'node:fs/promises'
import { recalculateSheetjsWorkbook } from '@bilig/sheetjs-formula-recalc'
const result = recalculateSheetjsWorkbook(await readFile('pricing.xlsx'), {
fileName: 'pricing.xlsx',
edits: [
{ target: 'Inputs!B2', value: 48 },
{ target: 'Inputs!B3', value: 1500 },
],
reads: ['Summary!B7'],
})
await writeFile('pricing.recalculated.xlsx', result.xlsx)
console.log({
value: result.reads['Summary!B7'],
warnings: result.warnings,
verified: result.warnings.length === 0,
})
The important rule is that your service owns the input cells, output cells, and verification checks. Do not read an arbitrary formula value and assume it is fresh just because an XLSX writer succeeded.
Proof against the common incumbents
The repository includes a bridge proof that edits the same workbook through
SheetJS/xlsx, xlsx-populate, and ExcelJS, then verifies that Bilig refreshes
the stale 48000 result to 72000 in all three paths:
git clone https://github.com/proompteng/bilig.git
cd bilig
npm --prefix examples/recalc-bridge-workflows install
npm --prefix examples/recalc-bridge-workflows run smoke
Use that example when you are deciding whether to keep your current file library and add recalculation, instead of rewriting the whole workbook pipeline.
Decision table
| Job | Use |
|---|---|
| Read or write many spreadsheet formats | SheetJS / xlsx |
| Generate a styled XLSX report for a human to open later | SheetJS, ExcelJS, or xlsx-populate |
| Ask Excel to recalculate when someone opens the file | workbook calc properties or Excel itself |
Recalculate SheetJS / xlsx bytes inside Node after changing inputs | @bilig/sheetjs-formula-recalc |
| Recalculate generic XLSX bytes from another writer | @bilig/xlsx-formula-recalc |
| Keep an ExcelJS workbook and add fresh formula readback | @bilig/exceljs-formula-recalc |
| Own formula-backed workbook state as JSON in a service | @bilig/workpaper |
| Need commercial SheetJS formula calculation support | evaluate SheetJS Pro |
Production checks
Before using this on a critical path, keep fixtures for:
- the exact workbook template your service receives or emits
- every input cell your code writes
- every output cell your code reads
- unsupported formulas and import warnings
- exported workbook reimport
- an Excel or LibreOffice oracle check for representative customer files
Bilig is not full Excel. The useful promise is narrower: a Node process can edit known input cells, recalculate supported formulas, read back known output cells, and export a workbook with tests around that boundary.
Related proof
- XLSX formula recalculation in Node.js
- Stale XLSX formula cache in Node.js
- SheetJS and ExcelJS boundary guide
- xlsx-populate formula results in Node.js
- ExcelJS formula recalculation in Node.js
- @bilig/xlsx-formula-recalc package
- @bilig/sheetjs-formula-recalc package
- SheetJS, xlsx-populate, and ExcelJS bridge example
After the proof
If the demo or a reduced SheetJS workbook returns the fresh formula values you needed, star the repository or bookmark Bilig so the boundary is easy to find later: https://github.com/proompteng/bilig/stargazers.
Watch releases if this is close to a production workflow: https://github.com/proompteng/bilig/subscription.
If a SheetJS workbook still fails after a reduced test case, open the blocker with the formula, input cells, output cells, and warning output: https://github.com/proompteng/bilig/discussions/new?category=general.
Sources
- SheetJS Cell Objects: https://docs.sheetjs.com/docs/csf/cell/
- SheetJS Formulae: https://docs.sheetjs.com/docs/csf/features/formulae
- SheetJS Parse Options: https://docs.sheetjs.com/docs/api/parse-options
xlsxnpm package: https://www.npmjs.com/package/xlsx@bilig/sheetjs-formula-recalcnpm package: https://www.npmjs.com/package/@bilig/sheetjs-formula-recalc@bilig/xlsx-formula-recalcnpm package: https://www.npmjs.com/package/@bilig/xlsx-formula-recalc