npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cellrune/node

v0.1.20

Published

Headless XLSX/XLSM reading, deterministic calculation, editing, and writing

Readme

@cellrune/node

Node.js bindings for CellRune, a headless XLSX/XLSM reader, deterministic calculation engine, editor, and writer.

Requirements

  • Node.js 22 or newer
  • A supported macOS, Linux, or Windows platform

The package installs the matching native package through an optional dependency. You do not need to select a platform package yourself.

Install

npm install @cellrune/[email protected]

CommonJS

const { Workbook } = require("@cellrune/node");

async function main() {
  const workbook = Workbook.create();
  try {
    workbook.setNumber("Sheet1", "A1", 41);
    workbook.setFormula("Sheet1", "B1", "=A1+1");
    await workbook.calculate();
    await workbook.save("output.xlsx");
  } finally {
    workbook.close();
  }
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

ES modules

import { Workbook } from "@cellrune/node";

const workbook = await Workbook.openPath("input.xlsx");
try {
  const page = workbook.readRange("Sheet1", "A1", "D20", { limit: 80 });
  console.log(page.cells);
} finally {
  workbook.close();
}

Verified change preview

previewChanges captures a revision-checked v2 edit candidate and calculates it without changing the live workbook. It is the only preview call that returns a Promise; page, commit, and discard are synchronous.

const revision = workbook.summary().semanticRevision;
const preview = await workbook.previewChanges(revision, [
  { kind: "setValue", sheet: "Sheet1", address: "A1", value: { kind: "number", value: 42 } },
]);

const page = workbook.previewChangesPage(preview.previewId, {
  section: "preview_results",
  limit: 100,
});

const receipt = workbook.commitPreview(preview.previewId);
// Or, without changing the workbook: workbook.discardPreview(preview.previewId);

Preview IDs and revision/cursor fields are bigint; preview DTO fields use camel case. A session retains no more than one active preview calculation and one published preview. A failed, cancelled, stale, or oversized replacement leaves a prior published preview available. Pre-commit cancellation or a resource error is retryable; a stale or successful commit consumes the preview. Pass an opaque PreviewCursor from previewChangesPage back unchanged for the same preview and section. The complete shared lifecycle and page contract is in llms.txt.

Calculate a few outputs before any full calculation with:

const result = await workbook.calculateTargets([
  { sheet: "Sheet1", start: "B1" },
  { sheet: "Sheet1", start: "D1", end: "D10" },
], { limits: { maxResultCells: 100, maxEvaluatedCells: 10000 } });

TargetCalculationResult has scope: "targets", a bigint semanticRevision, source identity, typed cells, deterministic options, limits, and evaluatedCount, parsedFormulaCount, and reusedCount. It includes only requested cells in sheet-ID and row-major order. Calculation parses/evaluates required precedents, deduplicates overlap, and can reuse a compatible current complete cache. It does not install a full cache, clear dirty formulas, advance deltas, invalidate a preview, or satisfy the full-calculation requirement for saving. Defaults allow 1024 targets, 10000 returned cells, and 100000 evaluator invocations, including dynamic retries. Known array followers evaluate the whole anchor; include the anchor when requesting an undeclared spill whose owner has not yet been calculated. Saved formula caches are never treated as current. Use declared spill ranges or full calculation if independent undeclared spills may overlap; anchors outside the dependency scope are not discovered by a partial request.

Workbook supports typed errors, revision-checked edit batches, incremental calculation deltas, deterministic todaySerial and nowSerial inputs, and explicit arithmeticSemantics / financialSolverSemantics compatibility policies. The latter accept "ieee_754" and "extended_search" when a caller needs the calculation behavior shipped through 0.1.2; omitted fields select the Excel-compatible defaults. The 0.1.14 calculation surface adds CONVERT, the four BESSEL* functions, and fourteen COMPLEX/IM* functions. They return scalar numbers or Excel-compatible complex text and expose the same catalog and calculation contract as Rust and Python. inspectDefinedName returns typed static, dynamic, empty, external, invalid, and unsupported defined-name results. applyChangesV2 retains every v1 edit shape and adds stable-ID table rename, table-column rename, and table-row resize operations with changedTableIds in its receipt. save() returns a WriteReport whose outputSha256 is the SHA-256 of the exact verified output archive bytes. It is an output identity, not the input document hash. close() is idempotent. Once it returns, the binding-owned native session has been released. An active calculation is cooperatively cancelled, a published preview is discarded, and later operations fail with interop.session.closed. See the declarations bundled with the package for the complete API.

CellRune is dual-licensed under either the MIT License or the Apache License, Version 2.0, at your option. Both texts ship with this package as LICENSE-MIT and LICENSE-APACHE. The native package's dependency notices are in THIRD_PARTY_LICENSES.md.