Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Node.js (Native Binding)

@goplasmatic/datalogic-node is the native Node.js binding: the Rust core compiled per platform and loaded through napi-rs, with no WebAssembly in between. On Node servers it is the fast path, running close to native Rust throughput.

Two npm packages, one engine. This package is for Node services that want maximum throughput. @goplasmatic/datalogic-wasm is the WebAssembly build: it also runs under Node, but its home turf is browsers, edge runtimes, Deno, and Bun. Same core, same semantics, same conformance battery either way.

Install

npm install @goplasmatic/datalogic-node

Prebuilt platform binaries are published as optionalDependencies, so npm pulls only the .node file matching your platform:

PlatformArchitectures
Linux (glibc)x64, arm64
Linux (musl)x64, arm64
macOSx64, arm64
Windowsx64, arm64

Node 18 and newer are supported. There is no build step and no WASM initialization: import and call.

Quick start

Rules and data are plain JavaScript objects; results come back as JavaScript values:

import { apply } from '@goplasmatic/datalogic-node';

const result = apply(
  { if: [{ '>': [{ var: 'score' }, 50] }, 'pass', 'fail'] },
  { score: 75 }
);
// -> "pass"

Compile once, evaluate many

For repeated evaluations of the same rule, compile once and hold the Rule instance:

import { Engine } from '@goplasmatic/datalogic-node';

const engine = new Engine();
const rule = engine.compile({ '+': [{ var: 'x' }, 1] });

for (const payload of inputs) {
  console.log(rule.evaluate(payload));
}

Rule is safe to share across worker threads: share one instance and evaluate concurrently.

Sessions: hot-loop arena reuse

A Session reuses one bump arena across evaluations and resets between calls to bound peak memory. Open one per worker thread:

const sess = engine.session();
for (const payload of inputs) {
  sess.evaluate(rule, payload);
}

Sessions hold non-Sync state and must not be shared between worker threads.

Error handling

Failures throw plain JS Error instances with structured fields attached:

try {
  rule.evaluate(data);
} catch (e) {
  if (e.name === 'ParseError') {
    // Malformed rule or data JSON
  } else if (e.name === 'EvaluateError') {
    console.log(e.errorType);  // stable tag (e.g. "TypeError", "Thrown")
    console.log(e.operator);   // outermost failing operator
    console.log(e.nodeIds);    // leaf-to-root breadcrumb
    console.log(e.path);       // resolved root-to-leaf step list
  }
}

API surface

SymbolDescription
apply(rule, data)One-shot compile + evaluate
new Engine(config?)Engine with optional configuration and custom operators
engine.compile(rule)Compile to a shareable Rule
rule.evaluate(data)Evaluate against one payload
engine.session()Arena-reusing session for hot loops

Engine configuration, custom operators, and tracing follow the same shapes as every other binding; the package README documents the full surface, and Configuration covers what each option means.

When to choose WASM instead

Choose @goplasmatic/datalogic-wasm when the code must run in a browser or edge runtime, or when you want one artifact across Node + browser. Choose this native package for Node services where throughput matters: the WASM build measures roughly 88× slower than the native core on the same benchmark workload.

Next steps