Gathering detailed insights and metrics for expr-eval-boss
Gathering detailed insights and metrics for expr-eval-boss
Gathering detailed insights and metrics for expr-eval-boss
Gathering detailed insights and metrics for expr-eval-boss
Mathematical expression evaluator in JavaScript
npm install expr-eval-boss
Typescript
Module System
Node Version
NPM Version
JavaScript (100%)
Total Downloads
10,298
Last Day
2
Last Week
26
Last Month
161
Last Year
3,625
MIT License
1,244 Stars
385 Commits
248 Forks
31 Watchers
5 Branches
29 Contributors
Updated on May 01, 2025
Minified
Minified + Gzipped
Latest Version
3.0.34
Package Id
expr-eval-boss@3.0.34
Unpacked Size
294.00 kB
Size
60.14 kB
File Count
7
NPM Version
8.19.3
Node Version
16.19.0
Published on
Nov 07, 2024
Cumulative downloads
Total Downloads
Last Day
0%
2
Compared to previous day
Last Week
-13.3%
26
Compared to previous week
Last Month
-25.8%
161
Compared to previous month
Last Year
3.4%
3,625
Compared to previous year
Parses and evaluates mathematical expressions. It's a safer and more math-oriented alternative to using
JavaScript’s eval
function for mathematical expressions.
It has built-in support for common math operators and functions. Additionally, you can add your own JavaScript functions. Expressions can be evaluated directly, or compiled into native JavaScript functions.
npm install expr-eval
1 const Parser = require('expr-eval').Parser; 2 3const parser = new Parser(); 4let expr = parser.parse('2 * x + 1'); 5console.log(expr.evaluate({ x: 3 })); // 7 6 7// or 8Parser.evaluate('6 * x', { x: 7 }) // 42
Parser is the main class in the library. It has as single parse
method, and
"static" methods for parsing and evaluating expressions.
Constructs a new Parser
instance.
The constructor takes an optional options
parameter that allows you to enable or disable operators.
For example, the following will create a Parser
that does not allow comparison or logical operators, but does
allow in
:
1 const parser = new Parser({
2 operators: {
3 // These default to true, but are included to be explicit
4 add: true,
5 concatenate: true,
6 conditional: true,
7 divide: true,
8 factorial: true,
9 multiply: true,
10 power: true,
11 remainder: true,
12 subtract: true,
13
14 // Disable and, or, not, <, ==, !=, etc.
15 logical: false,
16 comparison: false,
17
18 // Disable 'in' and = operators
19 'in': false,
20 assignment: false
21 }
22 });
Convert a mathematical expression into an Expression
object.
Static equivalent of new Parser().parse(expression)
.
Parse and immediately evaluate an expression using the values and functions from the variables
object.
Parser.evaluate(expr, vars) is equivalent to calling Parser.parse(expr).evaluate(vars).
Parser.parse(str)
returns an Expression
object. Expression
s are similar to JavaScript functions, i.e. they can
be "called" with variables bound to passed-in values. In fact, they can even be converted into JavaScript functions.
Evaluate the expression, with variables bound to the values in {variables}. Each variable in the expression is bound to
the corresponding member of the
variables
object. If there are unbound variables, evaluate
will throw an exception.
1 js > expr = Parser.parse("2 ^ x"); 2(2 ^ x) 3js > expr.evaluate({ x: 3 }); 48
Create a new Expression
with the specified variable replaced with another expression. This is similar to function
composition. If expression
is a string or number, it will be parsed into an Expression
.
1 js > expr = Parser.parse("2 * x + 1"); 2((2 * x) + 1) 3js > expr.substitute("x", "4 * x"); 4((2 * (4 * x)) + 1) 5js > expr2.evaluate({ x: 3 }); 625
Simplify constant sub-expressions and replace variable references with literal values. This is basically a partial evaluation, that does as much of the calculation as it can with the provided variables. Function calls are not evaluated (except the built-in operator functions), since they may not be deterministic.
Simplify is pretty simple. For example, it doesn’t know that addition and multiplication are associative,
so ((2*(4*x))+1)
from the previous example cannot be simplified unless you provide a value for x. 2*4*x+1
can
however, because it’s parsed as (((2*4)*x)+1)
, so the (2*4)
sub-expression will be replaced with "8", resulting
in ((8*x)+1)
.
1 js > expr = Parser.parse("x * (y * atan(1))").simplify({ y: 4 }); 2(x * 3.141592653589793) 3js > expr.evaluate({ x: 2 }); 46.283185307179586
Get an array of the unbound variables in the expression.
1 js > expr = Parser.parse("x * (y * atan(1))"); 2(x * (y * atan(1))) 3js > expr.variables(); 4x, y 5js > expr.simplify({ y: 4 }).variables(); 6x
By default, variables
will return "top-level" objects, so for example, Parser.parse(x.y.z).variables()
returns ['x']
. If you want to get the whole chain of object members, you can call it with { withMembers: true }
.
So Parser.parse(x.y.z).variables({ withMembers: true })
would return ['x.y.z']
.
Get an array of variables, including any built-in functions used in the expression.
1 js > expr = Parser.parse("min(x, y, z)"); 2(min(x, y, z)) 3js > expr.symbols(); 4min, x, y, z 5js > expr.simplify({ y: 4, z: 5 }).symbols(); 6min, x
Like variables
, symbols
accepts an option argument { withMembers: true }
to include object members.
Convert the expression to a string. toString()
surrounds every sub-expression with parentheses (except literal values,
variables, and function calls), so it’s useful for debugging precedence errors.
Convert an Expression
object into a callable JavaScript function. parameters
is an array of parameter names, or a string, with the names separated by commas.
If the optional variables
argument is provided, the expression will be simplified with variables bound to the supplied
values.
1 js > expr = Parser.parse("x + y + z"); 2((x + y) + z) 3js > f = expr.toJSFunction("x,y,z"); 4[Function] // function (x, y, z) { return x + y + z; }; 5js > f(1, 2, 3) 66 7js > f = expr.toJSFunction("y,z", { x: 100 }); 8[Function] // function (y, z) { return 100 + y + z; }; 9js > f(2, 3) 10105
The parser accepts a pretty basic grammar. It's similar to normal JavaScript expressions, but is more math-oriented. For
example, the ^
operator is exponentiation, not xor.
Operator | Associativity | Description |
---|---|---|
(...) | None | Grouping |
f(), x.y, a[i] | Left | Function call, property access, array indexing |
! | Left | Factorial |
^ | Right | Exponentiation |
+, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list) |
*, /, % | Left | Multiplication, division, remainder |
+, -, || | Left | Addition, subtraction, array/list concatenation |
==, !=, >=, <=, >, <, in | Left | Equals, not equals, etc. "in" means "is the left operand included in the right array operand?" |
and | Left | Logical AND |
or | Left | Logical OR |
x ? y : z | Right | Ternary conditional (if x then y else z) |
= | Right | Variable assignment |
; | Left | Expression separator |
1 const parser = new Parser({ 2 operators: { 3 'in': true, 4 'assignment': true 5 } 6 }); 7 // Now parser supports 'x in array' and 'y = 2*x' expressions
The parser has several built-in "functions" that are actually unary operators. The primary difference between these and
functions are that they can only accept exactly one argument, and parentheses are optional. With parentheses, they have
the same precedence as function calls, but without parentheses, they keep their normal precedence (just below ^
). For
example, sin(x)^2
is equivalent to
(sin x)^2
, and sin x^2
is equivalent to sin(x^2)
.
The unary +
and -
operators are an exception, and always have their normal precedence.
Operator | Description |
---|---|
-x | Negation |
+x | Unary plus. This converts it's operand to a number, but has no other effect. |
x! | Factorial (x * (x-1) * (x-2) * … * 2 * 1). gamma(x + 1) for non-integers. |
abs x | Absolute value (magnitude) of x |
acos x | Arc cosine of x (in radians) |
acosh x | Hyperbolic arc cosine of x (in radians) |
asin x | Arc sine of x (in radians) |
asinh x | Hyperbolic arc sine of x (in radians) |
atan x | Arc tangent of x (in radians) |
atanh x | Hyperbolic arc tangent of x (in radians) |
cbrt x | Cube root of x |
ceil x | Ceiling of x — the smallest integer that’s >= x |
cos x | Cosine of x (x is in radians) |
cosh x | Hyperbolic cosine of x (x is in radians) |
exp x | e^x (exponential/antilogarithm function with base e) |
expm1 x | e^x - 1 |
floor x | Floor of x — the largest integer that’s <= x |
length x | String or array length of x |
ln x | Natural logarithm of x |
log x | Natural logarithm of x (synonym for ln, not base-10) |
log10 x | Base-10 logarithm of x |
log2 x | Base-2 logarithm of x |
log1p x | Natural logarithm of (1 + x) |
not x | Logical NOT operator |
round x | X, rounded to the nearest integer, using "grade-school rounding" |
sign x | Sign of x (-1, 0, or 1 for negative, zero, or positive respectively) |
sin x | Sine of x (x is in radians) |
sinh x | Hyperbolic sine of x (x is in radians) |
sqrt x | Square root of x. Result is NaN (Not a Number) if x is negative. |
tan x | Tangent of x (x is in radians) |
tanh x | Hyperbolic tangent of x (x is in radians) |
trunc x | Integral part of a X, looks like floor(x) unless for negative number |
Besides the "operator" functions, there are several pre-defined functions. You can provide your own, by binding variables to normal JavaScript functions. These are not evaluated by simplify.
Function | Description |
---|---|
random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1. |
fac(n) | n! (factorial of n: "n * (n-1) * (n-2) * … * 2 * 1") Deprecated. Use the ! operator instead. |
min(a,b,…) | Get the smallest (minimum) number in the list. |
max(a,b,…) | Get the largest (maximum) number in the list. |
hypot(a,b) | Hypotenuse, i.e. the square root of the sum of squares of its arguments. |
pyt(a, b) | Alias for hypot. |
pow(x, y) | Equivalent to x^y. For consistency with JavaScript's Math object. |
atan2(y, x) | Arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians. |
roundTo(x, n) | Rounds x to n places after the decimal point. |
map(f, a) | Array map: Pass each element of a the function f , and return an array of the results. |
fold(f, y, a) | Array fold: Fold/reduce array a into a single value, y by setting y = f(y, x, index) for each element x of the array. |
filter(f, a) | Array filter: Return an array containing only the values from a where f(x, index) is true . |
indexOf(x, a) | Return the first index of string or array a matching the value x , or -1 if not found. |
join(sep, a) | Concatenate the elements of a , separated by sep . |
if(c, a, b) | Function form of c ? a : b. Note: This always evaluates both a and b , regardless of whether c is true or not. Use c ? a : b instead if there are side effects, or if evaluating the branches could be expensive. |
Arrays can be created by including the elements inside square []
brackets, separated by commas. For example:
[ 1, 2, 3, 2+2, 10/2, 3! ]
You can define functions using the syntax name(params) = expression
. When it's evaluated, the name will be added to
the passed in scope as a function. You can call it later in the expression, or make it available to other expressions by
re-using the same scope object. Functions can support multiple parameters, separated by commas.
Examples:
1 square(x) = x*x
2 add(a, b) = a + b
3 factorial(x) = x < 2 ? 1 : x * factorial(x - 1)
If you need additional functions that aren't supported out of the box, you can easily add them in your own code.
Instances of the Parser
class have a property called functions
that's simply an object with all the functions that
are in scope. You can add, replace, or delete any of the properties to customize what's available in the expressions.
For example:
1 const parser = new Parser(); 2 3// Add a new function 4parser.functions.customAddFunction = function (arg1, arg2) { 5 return arg1 + arg2; 6}; 7 8// Remove the factorial function 9delete parser.functions.fac; 10 11parser.evaluate('customAddFunction(2, 4) == 6'); // true 12//parser.evaluate('fac(3)'); // This will fail
The parser also includes a number of pre-defined constants that can be used in expressions. These are shown in the table below:
Constant | Description |
---|---|
E | The value of Math.E from your JavaScript runtime |
PI | The value of Math.PI from your JavaScript runtime |
true | Logical true value |
false | Logical false value |
Pre-defined constants are stored in parser.consts
. You can make changes to this property to customise the constants
available to your expressions. For example:
1 const parser = new Parser(); 2 parser.consts.R = 1.234; 3 4 console.log(parser.parse('A+B/R').toString()); // ((A + B) / 1.234)
To disable the pre-defined constants, you can replace or delete parser.consts
:
1 const parser = new Parser(); 2 parser.consts = {};
cd
to the project directorynpm install
npm test
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
0 existing vulnerabilities detected
Reason
license file detected
Details
Reason
Found 5/24 approved changesets -- score normalized to 2
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Score
Last Scanned on 2025-04-28
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More