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

@truecalc/core

v4.0.0

Published

Spreadsheet formula engine for the browser — Google Sheets–compatible formula evaluator compiled to WebAssembly

Readme

@truecalc/core

npm crates.io docs.rs license

WebAssembly-powered spreadsheet formula engine for JavaScript/TypeScript.

484 spreadsheet functions. Runs in Node.js, Bun, Deno, and the browser — no server needed. Ground-truth conformance against real Google Sheets. The same engine is also available as a Rust crate and as an MCP server for AI assistants.

const { evaluate } = require('@truecalc/core');
evaluate('SUM(A1, B1)', { A1: 100, B1: 200 })
// => { type: 'number', value: 300 }

Install

npm install @truecalc/core

Usage

Node.js (CJS)

Works out of the box — no bundler configuration needed.

const { evaluate, validate, list_functions } = require('@truecalc/core');

const result = evaluate('SUM(A1, B1)', { A1: 100, B1: 200 });
// => { type: 'number', value: 300 }

Vite

Install the wasm plugin first:

npm install -D vite-plugin-wasm

Add it to vite.config.js:

import wasm from 'vite-plugin-wasm';

export default {
  plugins: [wasm()],
};

Then import and use normally:

import { evaluate } from '@truecalc/core';

const result = evaluate('IF(A1 > 0, "yes", "no")', { A1: 1 });
// => { type: 'text', value: 'yes' }

webpack 5

webpack 5 supports WebAssembly natively. Enable the experiment in webpack.config.js:

module.exports = {
  experiments: {
    asyncWebAssembly: true,
  },
};

API

evaluate(formula, variables)

Evaluates a formula with the given variable bindings.

evaluate('SUM(A1, B1)', { A1: 100, B1: 200 })
// => { type: 'number', value: 300 }

evaluate('CONCAT("Hello, ", name)', { name: 'world' })
// => { type: 'text', value: 'Hello, world' }

Return value shape (a discriminated union tagged by type):

| type | Shape | |----------|--------------------------------------------------------| | number | { type: 'number', value: 6 } | | text | { type: 'text', value: 'yes' } | | bool | { type: 'bool', value: true } | | date | { type: 'date', value: 46180 } | | error | { type: 'error', error: '#NAME?' } | | empty | { type: 'empty' } | | array | { type: 'array', value: [ /* EvalResult cells */ ] } |

date carries a spreadsheet serial number (value); the epoch is implied by the engine flavor (google-sheets: day 0 = 1899-12-30). Format it yourself if you need a calendar date.

array is recursive: each element is itself an EvalResult, so a 1-D result is a flat value list of scalar cells and a 2-D result is a value list of array rows whose elements are scalar cells. Array cells keep their own type (including nested date/error/empty).

evaluate('SEQUENCE(2,2)')
// => {
//   type: 'array',
//   value: [
//     { type: 'array', value: [ { type: 'number', value: 1 }, { type: 'number', value: 2 } ] },
//     { type: 'array', value: [ { type: 'number', value: 3 }, { type: 'number', value: 4 } ] },
//   ],
// }

evaluate('TODAY()')
// => { type: 'date', value: 46180 }

Breaking change in 0.7.0 (surface shape)

0.7.0 ships the unspilled-array core change (see core PR #566 / issue #569). Two observable shapes changed for npm consumers:

  • Array-producing formulas (SORT, FILTER, UNIQUE, SEQUENCE, TRANSPOSE, MMULT, HSTACK/VSTACK, RANDARRAY, array literals, ...) now return a full { type: 'array', value: [...] } result. In <= 0.6.x these returned the top-left anchor-cell scalar (and, transiently after #566 but before this fix, an { type: 'error', error: 'array not supported' } object). To recover the old single-cell behavior, read the first cell yourself, e.g. const tl = r.type === 'array' ? r.value[0] : r; (recurse once more for 2-D).
  • Date-producing functions (TODAY, DATE, ...) now return { type: 'date', value } instead of { type: 'number', value }. If you were treating the result as a number, also accept type === 'date' (the value encoding is identical — a serial number).

validate(formula)

Checks whether a formula is syntactically valid without evaluating it.

validate('SUM(A1, B1)')  // => { valid: true }
validate('SUM(A1,')      // => { valid: false, error: '...' }

list_functions()

Returns metadata for all built-in functions as an array of { name, category, syntax, description }.

const fns = list_functions();
// [
//   { name: 'SUM',     category: 'math',     syntax: 'SUM(value1, ...)',   description: 'Sum of all arguments' },
//   { name: 'AVERAGE', category: 'math',     syntax: 'AVERAGE(value1, ...)', description: 'Arithmetic mean of all arguments' },
//   { name: 'IF',      category: 'logical',  syntax: 'IF(condition, value_if_true, value_if_false)', description: 'Conditional evaluation' },
//   ...
// ]

Available functions by category:

| Category | Functions | |------------|-----------| | math | SUM, AVERAGE, PRODUCT, ROUND, ROUNDUP, ROUNDDOWN, INT, ABS, SIGN, MOD, POWER, SQRT, LOG, LOG10, LN, EXP, CEILING, FLOOR, RAND, RANDBETWEEN, PI, SIN, COS, TAN, QUOTIENT | | logical | IF, AND, OR, NOT, IFERROR, IFNA, IFS, SWITCH, ISNUMBER, ISTEXT, ISERROR, ISBLANK, ISNA | | text | LEFT, MID, RIGHT, LEN, LOWER, UPPER, TRIM, CONCATENATE, FIND, SUBSTITUTE, REPLACE, TEXT, VALUE, REPT | | financial | PMT, NPV, IRR, PV, FV, RATE, NPER | | statistical | COUNT, COUNTA, MAX, MIN, MEDIAN |

Documentation

docs.truecalc.app