
Security News
Deno 2.6 + Socket: Supply Chain Defense In Your CLI
Deno 2.6 introduces deno audit with a new --socket flag that plugs directly into Socket to bring supply chain security checks into the Deno CLI.
json-expressions
Advanced tools
A JavaScript expression engine for JSON-based dynamic computations and function composition
A JavaScript expression engine for JSON-based dynamic computations and function composition. JSON Expressions provides a declarative syntax for creating complex logic, transformations, and calculations that can be serialized, stored, and executed safely.
Well-suited for configuration-driven applications, business rules engines, and anywhere you need dynamic logic represented as data.
npm install json-expressions
import {
createExpressionEngine,
mathPack,
comparisonPack,
} from "json-expressions";
// Create an engine with the packs you need
const engine = createExpressionEngine({ packs: [mathPack, comparisonPack] });
// Apply expressions to your data
const user = { age: 25, score: 85 };
// Simple comparisons
engine.apply({ $gt: 18 }, user.age); // true (25 > 18)
// Complex logic with input data
engine.apply(
{
$matchesAll: {
age: { $gte: 18 },
score: { $gt: 80 },
},
},
user,
); // true
JSON Expressions let you write logic as JSON that operates on input data. Each expression has a key starting with $ and describes what operation to perform:
// "Is the input greater than 18?"
{
$gt: 18;
}
// "Get the 'name' property from input"
{
$get: "name";
}
// "Filter input array for items with age >= 18"
{
$filterBy: {
age: {
$gte: 18;
}
}
}
Create custom expressions for your domain:
const engine = createExpressionEngine({
custom: {
$isValidEmail: (operand, inputData) =>
/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(inputData),
},
});
engine.apply({ $isValidEmail: null }, "user@example.com"); // true
Read more about creating custom expressions.
JSON Expressions is optimized for tree-shaking when using ESM imports. Import only the packs you need for optimal bundle sizes:
| Use Case | Bundle Size | Gzipped |
|---|---|---|
| Math pack only | 31 KB | 7 KB |
| Math + Array packs | 36 KB | 8 KB |
| All packs except temporal | 42 KB | 9 KB |
| With temporal (date/time) | 133 KB | 23 KB |
How it works:
// Import packs (recommended) - Modern bundlers tree-shake automatically
import { mathPack, createExpressionEngine } from "json-expressions";
const engine = createExpressionEngine({ packs: [mathPack] });
// Result: ~31 KB in your bundle (only math + engine)
// Import individual expressions for even smaller bundles
import {
$add,
$multiply,
$sum,
createExpressionEngine,
} from "json-expressions";
const customPack = { $add, $multiply, $sum };
const engine = createExpressionEngine({ packs: [customPack] });
// Result: ~28 KB in your bundle (only selected expressions + engine)
Requirements:
import, not require)Node.js with require(): Uses pre-built bundle (~71 KB with external dependencies). For smaller server bundles, use ESM imports in Node 16+.
JSON Expressions prioritizes flexibility over raw performance. This library is designed for scenarios where dynamic, data-driven logic is more valuable than execution speed. Performance is an important design goal to enable as many uses as possible, but it will never be a replacement for performance tuned code.
eval()const order = {
items: [{ price: 10 }, { price: 15 }],
tax: 0.08,
};
// Get nested data
engine.apply({ $get: "items" }, order);
// Returns: [{ price: 10 }, { price: 15 }]
// Transform arrays
engine.apply(
{
$pipe: [{ $get: "items" }, { $map: { $get: "price" } }, { $sum: null }],
},
order,
);
// Returns: 25 (sum of all prices)
const user = { status: "premium", age: 25 };
// Simple conditions
engine.apply(
{
$if: {
if: { $eq: [{ $get: "status" }, "premium"] },
then: "VIP Access",
else: "Standard Access",
},
},
user,
);
// Returns: "VIP Access"
// Complex case statements
engine.apply(
{
$case: {
value: { $get: "status" },
cases: [
{ when: "premium", then: "Gold Badge" },
{ when: "standard", then: "Silver Badge" },
],
default: "No Badge",
},
},
user,
);
// Returns: "Gold Badge"
const children = [
{ name: "Ximena", age: 4, active: true },
{ name: "Yousef", age: 5, active: false },
{ name: "Zoë", age: 6, active: true },
];
// Filter with complex conditions
engine.apply(
{
$filter: {
$and: [{ $get: "active" }, { $gte: [{ $get: "age" }, 5] }],
},
},
children,
);
// Returns: [{ name: "Zoë", age: 6, active: true }]
Before evaluating expressions, validate them to catch invalid operators:
const engine = createExpressionEngine();
// Get all validation errors (empty array = valid)
const errors = engine.validateExpression({ $get: "name" });
if (errors.length === 0) {
// Safe to evaluate
}
// Multiple errors returned at once
const errors = engine.validateExpression({
$pipe: [{ $bad1: "oops" }, { $bad2: "another" }],
});
// errors.length === 2
// Or ensure validity, throwing all errors
try {
engine.ensureValidExpression({ $typo: "bad" });
} catch (err) {
console.log(err.message);
// Unknown expression operator: "$typo". Did you mean "$gt"?
}
Both methods perform deep validation of nested expressions and correctly handle $literal operands.
Import only the functionality you need:
import {
createExpressionEngine,
mathPack, // $add, $subtract, $multiply, $divide, $sum, $mean, etc.
comparisonPack, // $eq, $ne, $gt, $lt, $gte, $lte, $in, $nin
arrayPack, // $filter, $map, $sort, $unique, $flatten, $groupBy
objectPack, // $pick, $omit, $merge, $keys, $values, $pairs
stringPack, // $concat, $join, $matchesRegex
filteringPack, // $filterBy, $find, $all, $any
projectionPack, // $select, $pluck
aggregationPack, // Statistical functions
temporalPack, // $addDays, $formatDate, $diffDays, $isAfter, etc.
} from "json-expressions";
const engine = createExpressionEngine({
packs: [mathPack, comparisonPack, arrayPack],
});
→ Complete Pack Reference - Detailed guide to all packs and their expressions
JSON Expressions is optimized for flexibility over raw execution speed. Expect:
Performance varies based on operation complexity:
| Operation Type | Performance | Example |
|---|---|---|
| Simple operations | 1-1.6M ops/sec | $gt, $get, $add |
| Complex operations | 300-700K ops/sec | $matchesAll, $filter |
| Nested data access | 2.4M ops/sec | $get: "user.profile.name" |
| Data processing | 70-300K ops/sec | Pipeline transformations |
| Large datasets (1000 items) | 1.6-3.9K ops/sec | Filtering, grouping |
Run npm run bench for detailed performance metrics on your hardware.
Well suited for configuration logic, business rules, and data processing. Consider direct JavaScript functions for performance-critical hot paths.
FAQs
A JavaScript expression engine for JSON-based dynamic computations and function composition
The npm package json-expressions receives a total of 9 weekly downloads. As such, json-expressions popularity was classified as not popular.
We found that json-expressions demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Deno 2.6 introduces deno audit with a new --socket flag that plugs directly into Socket to bring supply chain security checks into the Deno CLI.

Security News
New DoS and source code exposure bugs in React Server Components and Next.js: what’s affected and how to update safely.

Security News
Socket CEO Feross Aboukhadijeh joins Software Engineering Daily to discuss modern software supply chain attacks and rising AI-driven security risks.