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

@pro-fa/expreszo

v0.5.0

Published

Mathematical expression evaluator

Downloads

548

Readme

ExpresZo Typescript

npm CI codecov

A fast, safe, and extensible expression evaluator for JavaScript and TypeScript.

ExpresZo parses and evaluates expressions at runtime — a configurable alternative to eval() that won't execute arbitrary code. Use it to power user-facing formula editors, rule engines, template systems, or any place you need to evaluate dynamic expressions safely.

import { Parser } from '@pro-fa/expreszo';

const parser = new Parser();
parser.evaluate('price * (1 - discount)', { price: 100, discount: 0.2 }); // 80

Read full documentation

Why ExpresZo?

Fast

ExpresZo uses a Pratt parser — a top-down operator-precedence parsing algorithm that processes tokens in a single pass with no backtracking. Compared to the recursive-descent parser in the original expr-eval, this means:

  • Significantly faster parsing — simple expressions parse in microseconds, complex ones at 40,000+ ops/sec
  • Predictable performance — parsing time scales linearly with expression length, not exponentially with nesting depth
  • Better error messages — the parser knows exactly what it expected at each position, producing precise diagnostics instead of generic "parse error" messages
  • Depth-limited — a 256-level recursion cap prevents stack overflow from malicious or runaway input

Parsed expressions compile to an immutable AST that can be evaluated repeatedly against different variable sets with near-zero overhead.

Safe

ExpresZo is designed to be safe by default:

  • No code execution — expressions can only call explicitly registered functions, never arbitrary JavaScript
  • Prototype pollution protection — access to __proto__, prototype, and constructor is blocked
  • Recursion depth limit — deeply nested expressions are rejected at parse time
  • No eval() or new Function() — the entire evaluation runs on a stack-based AST walker

Extensible

Build exactly the parser you need:

import { defineParser, coreParser, withMath, withString } from '@pro-fa/expreszo';

// Tree-shakeable: only include what you use
const parser = defineParser({
  operators: [...coreParser.operators, ...withMath.operators, ...withString.operators],
  functions: [...coreParser.functions, ...withMath.functions, ...withString.functions],
});

Or use the full kitchen-sink parser with zero configuration:

const parser = new Parser(); // all built-in operators and functions included

Installation

npm install @pro-fa/expreszo

Quick Start

import { Parser } from '@pro-fa/expreszo';

const parser = new Parser();

// Parse once, evaluate many times
const expr = parser.parse('2 * x + 1');
expr.evaluate({ x: 3 });  // 7
expr.evaluate({ x: 10 }); // 21

// Or pass a resolver directly as the first argument
expr.evaluate((name) => name === 'x' ? { value: 3 } : undefined); // 7

// Rich expression language
parser.evaluate('user.name ?? "Anonymous"', { user: {} }); // "Anonymous"
parser.evaluate('CASE WHEN score >= 90 THEN "A" WHEN score >= 80 THEN "B" ELSE "C" END', { score: 85 }); // "B"

Key Features

| Category | Features | |----------|----------| | Operators | Arithmetic, comparison, logical, coalesce (??), ternary, assignment, member access | | Data types | Numbers, strings, booleans, arrays, objects, null, undefined | | Functions | 60+ built-in: math, string, array, object, type-checking, utility | | Custom functions | Register your own JavaScript functions callable from expressions | | Arrow functions | x => x * 2, (a, b) => a + b | | SQL CASE | CASE WHEN ... THEN ... ELSE ... END multi-way conditionals | | Object construction | { name: "Ada", score: x * 10 } | | Async support | Custom functions can return Promises; evaluate() auto-awaits | | Language service | Completions, hover docs, diagnostics, syntax highlighting for IDE integration | | TypeScript | Full type definitions, strict mode, no any leaks | | Tree-shakeable | Subpath imports (@pro-fa/expreszo/math, @pro-fa/expreszo/string, ...) for minimal bundles |

Playground

Try it live at the Playground — an interactive environment with code completions, syntax highlighting, and real-time evaluation.

Documentation

For Expression Writers

| Document | Description | |:---------|:------------| | Quick Reference | Cheat sheet of operators, functions, and syntax | | Expression Syntax | Complete syntax reference with examples |

For Developers

| Document | Description | |:---------|:------------| | Parser | Parser configuration, methods, and customization | | Expression | Expression object methods: evaluate, simplify, variables | | Advanced Features | Promises, custom resolution, type conversion, operator customization | | Language Service | IDE integration: completions, hover info, diagnostics, Monaco Editor | | MCP Server | Model Context Protocol server exposing the language service to AI assistants | | Migration Guide | Migrating from expr-eval, legacy mode, version history |

For Contributors

| Document | Description | |:---------|:------------| | Contributing | Development setup, code style, and PR guidelines | | Performance Testing | Benchmarks, profiling, and optimization guidance | | Breaking Changes | Version-by-version breaking change documentation |

Coming from expr-eval?

ExpresZo is a direct successor to expr-eval. Existing expressions work out of the box. A { legacy: true } option preserves older operator semantics while you migrate incrementally. See the Migration Guide for details.

Origins

Originally based on expr-eval 2.0.2, completely rewritten with a Pratt parser, immutable AST, modular architecture, TypeScript, and comprehensive testing using Vitest.

License

See LICENSE.txt for license information.