Exprify (Math Expression + Simplify) is a JavaScript expression evaluator library. It is designed for math applications, scientific computing, data visualization tools, calculators, and other complex workflows that run in the browser and in Node.js. It supports basic arithmetic, variables, user-defined functions, and built-in operators for comparison, logic, and string manipulation.
- Arithmetic & Variables - Determine the value of arithmetic expressions using addition, subtraction, multiplication, division, exponents, brackets, variables, and determinants.
- Unit conversion - Convert between various compatible units, including length, mass, time, temperature, area, volume, speed, and more.
- Matrix operations - Create matrices with built-in support for addition, multiplication, transpose, inverse, determinant, eigenvalues, and other common linear algebra operations.
- Complex numbers - Perform calculations using complex numbers in both Cartesian and polar forms. It supports arithmetic operations, powers, roots, adjoints, values, arguments, and complex-valued functions.
- Symbolic math - Work with algebraic expressions symbolically instead of numerically. Expand, simplify, factor, replace variables, and solve equations symbolically without losing mathematical accuracy.
- Arbitrary precision - Use arbitrary-precision arithmetic for calculations that exceed standard floating-point precision.
- Exact fractions - Use rational numbers as proper fractions instead of decimal equivalents. Perform math operations with accuracy and convert between fractional.
- Calculus & statistics - Use a wide collection of mathematical functions, including derivatives, integrations, limits, sums, probability distributions, descriptive statistics, regression, and other statistical operations.
- Lambda expressions - Define anonymous functions using the short lambda syntax for functional programming tasks like mapping, filtering, reducing, sorting, and applying custom logic to collections.
- Expression chaining - Chain multiple evaluations together while automatically preserving intermediate results. Reuse previous answers with
ans, build multi-step workflows, and finish computations with.done(). - State serialization - Save the complete evaluation state, including variables, settings, history, and context, then restore it later using serialization APIs for persistence or sharing.
- Degree-mode trig - Includes dedicated degree-mode functions such as
sind,cosd,tand, and their inverse counterparts.
npm install exprifyESM (Node.js / bundlers):
import Exprify from "exprify";
const expr = new Exprify();
expr.evaluate("5 + 7 * 2"); // 19
expr.setVariable("x", 10);
expr.evaluate("x + 5"); // 15CommonJS:
const Exprify = require("exprify");
const expr = new Exprify();
expr.evaluate("5 + 7 * 2"); // 19Browser (CDN):
<script src="https://unpkg.com/exprify"></script>
<script>
const expr = new Exprify();
expr.evaluate("(10 + 5) * 2"); // 30
</script>Creates a new evaluator instance with fully isolated state. Each instance maintains its own independent registry of variables, custom functions, unit definitions, and a compiled-expression cache - so multiple instances never interfere with each other.
const expr = new Exprify();Parses and evaluates an expression string, returning the computed result. An optional scope object lets you pass temporary variable values that apply only to that single call - they do not modify the instance's stored state.
expr.evaluate("10 + 5 * 2"); // 20
expr.setVariable("x", 100);
expr.evaluate("x + 1", { x: 5 }); // 6 (x = 100 is unchanged)Parses an expression without evaluating it. Returns a { tokens, ast } object containing the raw token list and the abstract syntax tree - useful for debugging, introspection, or building custom tooling on top of the parser.
const { tokens, ast } = expr.parse("2 inch to cm");
// tokens: [...], ast: { type: "UnitConversion", ... }Compiles an expression once and returns a reusable callable function. The compiled form skips parsing on every subsequent invocation, making this the right choice for hot paths or any expression evaluated repeatedly with different inputs.
const area = expr.compile("width * height");
area({ width: 6, height: 4 }); // 24
area({ width: 3, height: 9 }); // 27Stores a named value that persists across all future evaluations on this instance. getVariable retrieves a previously stored value by name.
expr.setVariable("x", 10);
expr.setVariable("y", 5);
expr.evaluate("x + y * 2"); // 20
expr.getVariable("x"); // 10Registers a plain JavaScript function under a given name, making it available to call inside any expression evaluated on this instance. The function receives its arguments as individual parameters, exactly as written in the expression.
expr.addFunction("double", (n) => n * 2);
expr.evaluate("double(5) + 3"); // 13
expr.addFunction("clamp", (val, lo, hi) => Math.min(Math.max(val, lo), hi));
expr.evaluate("clamp(150, 0, 100)"); // 100Returns a fluent Chain object for building multi-step calculations. Each call to .evaluate() on the chain stores its result in the special variable ans, which the next expression can reference directly. Call .done() at the end to extract the final value.
const c = expr.chain();
c.setVariable("x", 25);
c.evaluate("sqrt(x) + 3"); // computes 8, stored as ans
c.evaluate("ans * 2"); // computes 16, stored as ans
c.done(); // 16Serializes the complete engine state - all variables, registered functions, and unit definitions - into a plain object that can be stored, transmitted, or restored later. importState loads a previously exported snapshot into a fresh instance, fully reconstructing that environment.
const state = expr.exportState();
// {
// variables: { x: 10, y: 5 },
// functions: ["double", "clamp"],
// units: {...}
// }
const expr2 = new Exprify();
expr2.importState(state);
expr2.evaluate("x + y"); // 15Functions can be defined directly inside an expression using the name(params) = body syntax. Once defined, they behave exactly like functions registered via addFunction and remain available for the lifetime of the instance.
expr.evaluate("hyp(a, b) = sqrt(a^2 + b^2)");
expr.evaluate("hyp(3, 4)"); // 5
expr.evaluate("hyp(5, 12)"); // 13This is particularly convenient for one-off helpers that do not warrant a full addFunction call, or for expressions that define and immediately use a function in a single evaluation step.
See the full searchable function reference for all ~130 built-in functions.
git clone https://github.com/code-hemu/exprify.git
cd Exprify
npm install
npm run buildOutput is written to dist/.
npm testTested in CI across Node 20 and 22. See .github/workflows/ci.yml for details.
- Fork the repository.
- Create a branch:
git checkout -b feature/your-feature - Commit your changes:
git commit -m "Add your feature" - Push and open a pull request.
Exprify is licensed under GPL-3.0. Copyright © Nirmal Paul.
