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.

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')]
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');
npm install punyexpr
yarn add punyexpr
pnpm add punyexpr

Shows basic usage: compile and evaluate, custom regex option, and the propertyOf hook.

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)