Simple JavaScript Expression Evaluator
simple-eval is a focused JavaScript library designed for evaluating simple expressions safely, providing an alternative to the native `eval()` function with a controlled execution environment. The current stable version is 2.0.0. It aims for a moderate release cadence, primarily for maintenance, bug fixes, or minor feature additions. A key differentiator is its limited instruction set, which enhances security by disallowing declarations, assignments, and complex statements, making it safer than direct `eval` for untrusted input, though it does not provide a full sandbox. It uses `jsep` as the default AST parser but supports any ESTree compliant parser like `acorn`, `@babel/parser`, or `esprima`, offering flexibility in parsing logic. This makes it suitable for scenarios requiring lightweight, controlled expression evaluation.
Common errors
-
ReferenceError: <variable> is not defined
cause Attempting to access a variable or function within the evaluated expression that was not passed in the context object.fixEnsure all variables, objects, and functions required by the expression are explicitly provided in the second argument to `simpleEval`. Example: `simpleEval('myVar + 1', { myVar: 10 })`. -
SyntaxError: Unexpected token
cause The evaluated string contains unsupported syntax like variable declarations (`const`, `let`, `var`), function declarations, or assignments (`=`).fixRemove all declarations and assignments from the expression. `simple-eval` is designed for expressions only. If you need to mutate state, do so outside the evaluation and pass the updated values in the context. -
TypeError: Cannot read properties of undefined (reading 'prop')
cause An object or property within the expression is `undefined` at the time of evaluation.fixCheck the context object and the expression logic to ensure all object paths are valid and defined. For optional chaining-like behavior, use ternary operators or logical AND (`&&`) within the expression: `user && user.profile && user.profile.name`.
Warnings
- gotcha simple-eval is not a full replacement for `eval` and should not be treated as a general-purpose JavaScript interpreter. It intentionally limits supported language features to enhance safety and predictability.
- breaking Declarations (e.g., `const`, `let`, `var`, `function`) and assignments (e.g., `x = 5`, `obj.prop = value`) are explicitly prohibited within the evaluated expressions. Attempting to use them will result in an error.
- gotcha The library does not provide a robust security sandbox. While it restricts many dangerous operations, it is not designed to run arbitrary untrusted code in a secure, isolated environment.
- gotcha By default, `simple-eval` uses the `jsep` parser. If you encounter parsing issues with specific syntaxes or wish to leverage advanced parsing features (e.g., JSX, Flow, TypeScript), you may need to provide a different ESTree-compliant parser.
Install
-
npm install simple-eval -
yarn add simple-eval -
pnpm add simple-eval
Imports
- simpleEval
const simpleEval = require('simple-eval');import simpleEval from 'simple-eval';
- SimpleEvalFunction
import type { SimpleEvalFunction } from 'simple-eval'; - CustomParserOptions
import type { CustomParserOptions } from 'simple-eval';
Quickstart
import simpleEval from 'simple-eval';
// Basic arithmetic evaluation
const result1 = simpleEval('2 + 4 * 10 + -4');
console.log(`'2 + 4 * 10 + -4' evaluates to: ${result1}`); // Expected: 38
// Using a context object for external variables or functions
const context = {
Math,
user: {
name: 'Alice',
age: 30,
isAdmin: true
},
greet: (name) => `Hello, ${name}!`
};
const result2 = simpleEval('Math.floor(Math.PI * 10)', context);
console.log(`'Math.floor(Math.PI * 10)' with Math context evaluates to: ${result2}`); // Expected: 31
const result3 = simpleEval('user.isAdmin ? greet(user.name) : \'Access Denied\'', context);
console.log(`Conditional access with custom function and object: ${result3}`); // Expected: 'Hello, Alice!'
// Attempting to use an undeclared variable (will throw if not in context)
try {
simpleEval('unknownVariable + 5');
} catch (e) {
console.error(`Error evaluating 'unknownVariable + 5': ${e.message}`); // Expected: 'unknownVariable is not defined'
}