punyexpr
raw JSON → 1.3.1 verified Fri May 01 auth: no javascript
A minimalist (5144 bytes), zero-dependency expression compiler and evaluator for JavaScript. Current stable version is 1.3.1, released on an ongoing basis with fixes and features. It compiles expression strings into reusable functions that evaluate against a context object, supporting arithmetic, string operations, member access, function calls, and ternary expressions. It does NOT support bitwise, async, coalesce, new, this, or object literals. Regular expressions are disabled by default for security (ReDoS) and can be enabled via an option. The library includes TypeScript type definitions and is compliant with Content Security Policy (CSP). It is a safer alternative to eval() or new Function() for dynamic expressions.
Common errors
error TypeError: (intermediate value).match is not a function ↓
cause Regular expression is not allowed by default; the expression parser treats /.../ as division.
fix
Enable regex by passing { regex: true } in compile options: punyexpr('value.match(/pattern/)', { regex: true })
error Error: Punyexpr compilation error: Unexpected token '?' (at column ...) ↓
cause Nullish coalescing operator (??) is not supported.
fix
Replace '??' with a ternary or logical OR: e.g., 'a ?? b' becomes 'a !== null && a !== undefined ? a : b'
error SyntaxError: Unexpected token '.' (at column ...) ↓
cause Optional chaining (?.) is not supported.
fix
Use a propertyOf hook or guard with conditionals: e.g., 'a?.b' becomes 'a && a.b' if you know a is truthy.
error TypeError: punyexp.propertyOf is not a function ↓
cause Using propertyOf with a version earlier than 1.3.0 or misspelling (punyexp vs punyexpr).
fix
Update to punyexpr@1.3.0 or later, and use the correct symbol: punyexpr[Symbol.for('punyexpr.propertyOf')]
Warnings
gotcha Regular expressions are disabled by default to prevent ReDoS attacks. Enabling them requires explicit opt-in via { regex: true }. ↓
fix Pass { regex: true } or a custom regex builder in the options.
deprecated The default export (punyexpr.default) is deprecated and was never officially supported. Use named import 'punyexpr' instead. ↓
fix Replace 'import punyexpr from "punyexpr"' with 'import { punyexpr } from "punyexpr"'.
breaking In versions prior to 1.2.0, TypeScript type definitions were incorrect or missing. Upgrading may require fixes in type usage. ↓
fix Update to punyexpr@1.2.0 or later and adjust any type annotations if needed.
gotcha The library does not support 'new', 'this', object literals, bitwise operators, async/await, or nullish coalescing. Expressions using these will throw a compile error. ↓
fix Avoid unsupported syntax in expressions. See documentation for supported grammar.
gotcha When using CommonJS, require('punyexpr') returns an object with a 'punyexpr' property (named export). Do not use require('punyexpr').punyexpr directly as it may confuse bundlers. ↓
fix Use destructuring: const { punyexpr } = require('punyexpr');
Install
npm install punyexpr yarn add punyexpr pnpm add punyexpr Imports
- punyexpr wrong
const punyexpr = require('punyexpr'); console.log(punyexpr('1+1')({}));correctimport { punyexpr } from 'punyexpr' - punyexpr.compile wrong
import { punyexpr } from 'punyexpr'; const compile = punyexpr.compile;correctimport { compile } from 'punyexpr' - punyexpr.propertyOf wrong
import { punyexpr } from 'punyexpr'; const propertyOf = punyexpr.propertyOf;correctimport { propertyOf } from 'punyexpr'
Quickstart
import { punyexpr } from 'punyexpr';
// Compile an expression
const inc = punyexpr('value + 1');
// Evaluate with a context
console.log(inc({ value: 1 })); // 2
// Compile with options (regex disabled by default)
const withRegex = punyexpr('name.match(/^A/i)', { regex: true });
console.log(withRegex({ name: 'Alice' })); // ['Alice']
// Use propertyOf hook (since v1.3.0)
const ctx = {
[Symbol.for('punyexpr.propertyOf')]: (value, prop) =>
value === undefined ? undefined : value[prop]
};
console.log(punyexpr('a.b')(ctx)); // undefined (a is undefined)