
Product
Introducing Repository Access Permissions and Custom Roles
Socket now supports Custom Roles and Repository Access Permissions so organizations can control who can access specific repositories and actions.
@pro-fa/expreszo
Advanced tools
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
This package is the core. Two optional companions extend it without bloating the core install — pick them up only when you need them:
@pro-fa/expreszo-datetime — ~70 Luxon-backed date/time functions (now, parseISO, addDuration, format, isWeekend, daysUntil, toRelative, dateRange, …). Polymorphic inputs accept Luxon DateTime, JS Date, ISO strings, and millisecond timestamps. The core never imports Luxon.@pro-fa/expreszo-mcp-server — MCP server that exposes the language service to AI assistants (Claude Desktop, Claude Code, Cursor, …). Ships an expreszo-mcp CLI.Companions register with the new parser.use(plugin) API:
import { defineParser, fullParser } from '@pro-fa/expreszo';
import { dateTimePlugin } from '@pro-fa/expreszo-datetime';
const parser = defineParser({ ...fullParser }).use(dateTimePlugin);
parser.parse("format(addDuration(now(), 7, 'days'), 'yyyy-MM-dd')").evaluate();
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:
Parsed expressions compile to an immutable AST that can be evaluated repeatedly against different variable sets with near-zero overhead.
ExpresZo is designed to be safe by default:
__proto__, prototype, and constructor is blockedeval() or new Function() — the entire evaluation runs on a stack-based AST walkerBuild 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
npm install @pro-fa/expreszo
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"
| 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 |
Try it live at the Playground — an interactive environment with code completions, syntax highlighting, and real-time evaluation.
| Document | Description |
|---|---|
| Quick Reference | Cheat sheet of operators, functions, and syntax |
| Expression Syntax | Complete syntax reference with examples |
| Date / Time functions | ~70 date/time functions (provided by the optional @pro-fa/expreszo-datetime package) |
| Document | Description |
|---|---|
| Parser | Parser configuration, methods, customization, and the parser.use(plugin) API |
| Expression | Expression object methods: evaluate, simplify, variables |
| Advanced Features | Promises, custom resolution, type conversion, operator customization |
| Date / Time integration | Wiring @pro-fa/expreszo-datetime into a parser |
| 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 |
| 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 |
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.
Originally based on expr-eval 2.0.2, completely rewritten with a Pratt parser, immutable AST, modular architecture, TypeScript, and comprehensive testing using Vitest.
The repo is a yarn workspace monorepo with three published packages under packages/:
| Package | Path |
|---|---|
@pro-fa/expreszo | packages/expreszo/ |
@pro-fa/expreszo-datetime | packages/expreszo-datetime/ |
@pro-fa/expreszo-mcp-server | packages/expreszo-mcp-server/ |
yarn install --frozen-lockfile # install all workspaces
yarn workspaces run lint # eslint all packages
yarn workspaces run type-check # tsc/tsgo on all packages
yarn workspaces run build # produce dist/ for each package
yarn workspaces run test # build + vitest in each package
This file (README.md) is the canonical README. The publish workflow copies it into packages/expreszo/ before npm publish, so the npm package always ships the same content.
See LICENSE.txt for license information.
FAQs
Mathematical expression evaluator
The npm package @pro-fa/expreszo receives a total of 83 weekly downloads. As such, @pro-fa/expreszo popularity was classified as not popular.
We found that @pro-fa/expreszo demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket now supports Custom Roles and Repository Access Permissions so organizations can control who can access specific repositories and actions.

Product
Socket MCP now lets AI assistants review org alerts, investigate threats using the Socket threat feed, and inspect package files in addition to dependency scoring.

Product
Socket Firewall blocks malicious VS Code and Open VSX extensions before install, protecting developers from compromised editor marketplaces.