jsep: Tiny JavaScript Expression Parser
jsep is a lightweight and tiny JavaScript expression parser, currently at a stable version 1.4.0. It is designed specifically for parsing JavaScript expressions, akin to formulas in a spreadsheet, rather than full JavaScript statements or operations. This focus allows it to remain compact compared to more comprehensive parsers like Esprima, while producing an Abstract Syntax Tree (AST) output that is largely compatible with Esprima and SpiderMonkey's Parser API. The library features a flexible plugin architecture, enabling users to extend its capabilities with support for custom operators, literals, and more advanced syntax (e.g., ternary, object literals, async/await) via separate `@jsep-plugin/*` packages. Recent updates, including features like nullish coalescing and exponentiation, suggest an active, albeit not rapid, release cadence.
Common errors
-
TypeError: jsep is not a function
cause In CommonJS environments, `require('jsep')` returns the module object, not the default parsing function directly. The parsing function is available via `.default`.fixChange `const jsep = require('jsep');` to `const jsep = require('jsep').default;` -
SyntaxError: Unexpected token
cause Attempting to parse a JavaScript statement (e.g., variable declarations, control flow) or an unsupported expression feature (like object literals, arrow functions) without the corresponding plugin registered.fixEnsure the input is a valid JavaScript expression. If using advanced syntax, verify that the necessary `@jsep-plugin/*` packages are installed and registered via `jsep.plugins.register()`. -
TypeError: Cannot read properties of undefined (reading 'register')
cause Attempting to call `jsep.plugins.register` before `jsep` has been imported, or if `jsep` was imported incorrectly (e.g., `import { Jsep } from 'jsep';` and then trying `Jsep.plugins.register`).fixEnsure `jsep` is correctly imported as the default export (e.g., `import jsep from 'jsep';` for ESM or `const jsep = require('jsep').default;` for CJS) before attempting to access its `plugins` property.
Warnings
- gotcha jsep is strictly an 'expression parser' and cannot parse full JavaScript statements (e.g., `if`, `for`, `var`). Attempting to parse statements will result in syntax errors.
- gotcha Many common JavaScript features (like object literals, arrow functions, `new` expressions, async/await, regex literals) are implemented as separate `@jsep-plugin/*` packages and are not included by default. These plugins must be explicitly installed and registered.
- breaking Major version upgrades (e.g., from v0.x to v1.x) historically introduced breaking changes, particularly in the structure of the generated Abstract Syntax Tree (AST) and the API for developing custom plugins. Always consult the migration guide when upgrading major versions.
- gotcha When defining custom operators, incorrect precedence or associativity can lead to unexpected parsing results. Precedence is numerical (higher = tighter binding); associativity (left-to-right or right-to-left) is crucial for operators like exponentiation.
Install
-
npm install jsep -
yarn add jsep -
pnpm add jsep
Imports
- jsep
const jsep = require('jsep');import jsep from 'jsep';
- Jsep
import Jsep from 'jsep';
import { Jsep } from 'jsep'; - jsep.plugins.register
import { Jsep } from 'jsep'; Jsep.plugins.register(myPlugin);import jsep from 'jsep'; import ternary from '@jsep-plugin/ternary'; jsep.plugins.register(ternary);
- jsep.addBinaryOp
import { Jsep } from 'jsep'; Jsep.addBinaryOp('^', 10);import jsep from 'jsep'; jsep.addBinaryOp('^', 10);
Quickstart
import jsep from 'jsep';
import ternary from '@jsep-plugin/ternary';
// Register a built-in plugin (ternary is default but shown for illustration)
jsep.plugins.register(ternary);
// Add a custom operator (e.g., bitwise XOR)
jsep.addBinaryOp('^', 10);
// Parse a simple expression
const simpleAst = jsep('1 + 2 * 3');
console.log('Simple AST:', JSON.stringify(simpleAst, null, 2));
// Parse an expression with a custom operator
const customOpAst = jsep('5 ^ 3');
console.log('Custom Operator AST:', JSON.stringify(customOpAst, null, 2));
// Parse a complex expression with ternary operator
const complexAst = jsep('a > b ? a : b');
console.log('Complex AST (ternary):', JSON.stringify(complexAst, null, 2));
// Demonstrate AST structure for a nullish coalescing operator (introduced in v1.4.0)
const nullishCoalescingAst = jsep('value ?? defaultValue');
console.log('Nullish Coalescing AST:', JSON.stringify(nullishCoalescingAst, null, 2));