Skip to main content
Install the ZEN Engine and evaluate your first decision in Node.js.

Installation

Basic usage

Loaders

Loaders let the engine resolve decisions by key - engine.evaluate('pricing.json', ...) - instead of you reading files by hand. Pass one to the ZenEngine constructor: either a built-in loader config (static, fs, or zip) or a custom async function.

Static

The static loader serves decisions from an in-memory map. Use it when your rules ship with the application or arrive as one payload:

File system

The fs loader resolves keys against a root directory - pricing.json maps to ./rules/pricing.json:

Zip archive

The zip loader unpacks an archive in memory; every .json entry becomes a decision keyed by its path in the archive. This pairs naturally with release ZIPs downloaded from the BRMS or object storage:

Custom loader

For any other backend - a database, a remote API, per-tenant storage - pass an async function. Combine it with ZenDecisionContent to cache pre-compiled decisions:

Batch evaluation

Evaluate many requests in one call. Each result reports its own success or failure, so one bad input never fails the batch:

Error handling

Using try-catch:
Using safeEvaluate:

Tracing

Enable tracing to inspect decision execution:

Expression utilities

Evaluate ZEN expressions outside of a decision context:
Synchronous versions are also available:

Best practices

Use ZenDecisionContent for caching. Pre-compiling decisions avoids repeated parsing overhead. Cache compiled content in a Map keyed by decision name. Initialize the engine once. Create a single ZenEngine instance at application startup and reuse it for all evaluations. Prefer built-in loaders. The static, fs, and zip loaders cover most setups without custom code; reserve callback loaders for backends the built-ins can’t reach. Call dispose() on shutdown. Release engine resources when your application terminates to prevent memory leaks.