Skip to content

GoPlasmatic/datalogic-rs

Plasmatic Logo

datalogic-rs

Business rules as data. One engine, every runtime.

Write a JSONLogic rule once and evaluate it with the exact same engine in Rust, Node.js, the browser (WASM), Python, Go, Java, .NET, and PHP. Not eight reimplementations that drift apart: one Rust core under every binding, evaluating in nanoseconds. Store rules as JSON, change pricing, eligibility, and flag logic in production, and never redeploy to do it.

CI Release Conformance License: Apache 2.0

πŸš€ Try the Live Playground | πŸ“– Read the Documentation


JSONLogic Online Debugger Demo

Build, trace, and debug rules live in the playground.


Why datalogic-rs?

  • 🌐 One rule, every runtime: every binding runs the same compiled Rust core, so a rule evaluates with identical semantics on your backend, your edge workers, and your frontend. No cross-language drift, verified by a 1,565-case conformance battery in CI.
  • πŸ”’ 100% sandbox-safe: evaluate user-submitted rules and formulas without arbitrary code execution. No eval(), no scripting runtime, no I/O; the core forbids unsafe code.
  • ⚑ Nanosecond evaluation: rules compile to OpCode-dispatched programs that run in a reusable memory arena: 10.3 ns geomean, 7.0Γ— the fastest JS engine, 83.6Γ— the reference implementation.
  • πŸ› οΈ Ready-made rule builder: ship a visual editor and step-through debugger to your product dashboard with the companion React component, instead of building rule UI from scratch.

One rule, every runtime

Rules are plain JSON, so there is exactly one of them, no matter how many languages you run:

Rule:   {"and": [{">=": [{"var": "age"}, 18]}, {"==": [{"var": "status"}, "active"]}]}
Data:   {"age": 25, "status": "active"}
Result: true

The same evaluation, one line in each runtime:

Runtime One-shot evaluation
Rust datalogic_rs::eval_str(rule, data)?
Node.js apply(rule, data) β€” @goplasmatic/datalogic-node
Browser / Edge (WASM) evaluate(rule, data, false) β€” @goplasmatic/datalogic-wasm
Python apply(rule, data) β€” datalogic_py
Go datalogic.Apply(rule, data)
Java / Kotlin engine.apply(rule, data)
.NET (C#) engine.Apply(rule, data)
PHP $engine->apply($rule, $data)

Same bytes in, same bytes out: every binding wraps the same core and passes the same 54-suite conformance battery. Each package README has the full quickstart for its language, and every binding ships the same three runnable programs under its examples/ folder β€” the folders themselves are the parity demo.


Pick your package

Language / Environment Version Package Install Guide
Rust Crates.io datalogic-rs cargo add datalogic-rs crate README
Node.js (native prebuilds) npm @goplasmatic/datalogic-node npm i @goplasmatic/datalogic-node node README
Browser, Edge, Bun, Deno npm @goplasmatic/datalogic-wasm npm i @goplasmatic/datalogic-wasm wasm README
Python PyPI datalogic-py pip install datalogic-py python README
Go Go Reference datalogic-go go get github.com/GoPlasmatic/datalogic-rs/bindings/go/v5 go README
Java / JVM (Kotlin, Scala) Maven Central io.github.goplasmatic:datalogic Maven / Gradle dependency jvm README
.NET (C#, F#) NuGet Goplasmatic.Datalogic dotnet add package Goplasmatic.Datalogic dotnet README
PHP Packagist goplasmatic/datalogic composer require goplasmatic/datalogic php README
C / FFI (embed anywhere) built in-tree datalogic-c built locally c README
React visual editor npm @goplasmatic/datalogic-ui npm i @goplasmatic/datalogic-ui ui README

Three things you can build

1. Dynamic business rules

Encode pricing logic, fee schedules, eligibility and underwriting rules, transaction risk scoring, payment routing, access control, or form validation as JSON. Store rules in a database column, fetch them from an API, review them in a diff: logic changes ship without a deploy.

Rule:   {"if": [
          {">": [{"var": "cart.total"}, 100]}, "free-shipping",
          {">": [{"var": "cart.total"}, 50]},  "flat-rate",
          "standard"
        ]}
Data:   {"cart": {"total": 127.5}}
Result: "free-shipping"

2. JSON response templates

Enable templating mode and JSON key-value structures flow through to the output, with operators computing fields in place:

Template: {"greeting": {"cat": ["Hello ", {"var": "name"}]},
           "isAdult":  {">=": [{"var": "age"}, 18]}}
Data:     {"name": "Jane", "age": 25}
Output:   {"greeting": "Hello Jane", "isAdult": true}

Templating is an engine option in every binding (in Rust: Engine::builder().with_templating(true), behind the templating feature).

3. Safe user expressions

Let power users and admins write formulas without handing them a scripting engine:

Rule:   {"+": [{"var": "subtotal"}, {"var": "tax"}, {"var": "shipping"}]}
Data:   {"subtotal": 100, "tax": 8.5, "shipping": 5}
Result: 113.5

Try any of these live in the playground, or browse the use-case cookbook for feature flags, fraud scoring, and data transformation recipes.


🎨 Visual rule builder and debugger

For admin portals and dashboards where non-engineers author rules, drop @goplasmatic/datalogic-ui into your React app. It runs the WASM core internally to compile and trace execution live, and it is the same component behind the online playground.

import { DataLogicEditor } from '@goplasmatic/datalogic-ui';

<DataLogicEditor
  value={{ ">": [{ "var": "x" }, 10] }}
  data={{ x: 42 }}
  onChange={(newRule) => console.log('Rules modified:', newRule)}
/>

One API shape, every binding

Every binding exposes the same seven patterns, so knowledge transfers across your stack:

Pattern Shape Use when
One-shot apply(rule, data) ad-hoc evaluation, scripts, low volume
Engine construct with config / custom operators non-default semantics, extensions
Compile once engine.compile(rule) β†’ evaluate many one rule, many payloads
Session engine.session() hot loops; reuses the internal arena across evaluations
Parse once DataHandle(json) β†’ evaluate many rules against it one payload, many rules or repeat evaluations; skips the dominant per-call parse cost
Typed session.evaluateBool/Number/Truthy(rule, handle) predicates and scalar results; no JSON decode on the way out
Batch session.evaluateBatch(rule, handles) / evaluateMany(rules, handle) many evaluations in one call, per-item errors that never fail the set

Rust adds two more tiers: zero-copy evaluation into a caller-owned arena, and traced evaluation powering the visual debugger. See the Rust crate deep-dive for the full ladder.


Performance

Geomean execution time across 51 benchmark suites (Apple M2 Pro; median of 3 samples; ratios are pairwise shared-suite geomeans; methodology in tools/benchmark/BENCHMARK.md):

datalogic-rs (native Rust)              | 10.3 ns  (β– ) 1x
json-logic-engine (JS, compiled)        | 63.3 ns  (β– β– β– β– β– β– ) 7.0x
json-logic-engine (JS, interpreted)     | 234.8 ns (β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– ) 25.8x
jsonlogic-rs (bestowinc Rust engine)    | 264.2 ns (β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– ) 28.1x
json-logic-js (Reference JS library)    | 465.1 ns (β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– β– ) 83.6x

Rules compile to a simple AST with OpCode dispatch (no runtime string matching) and execute inside a reusable memory arena: single-digit nanoseconds for folded rules, 10-120 ns for context-dependent ones.

In Node.js, the native @goplasmatic/datalogic-node package is the fast path and runs close to native Rust. The WASM build trades speed for portability (900.5 ns geomean under Node, 88Γ— native, but it runs anywhere JavaScript does). Use native on Node servers; use WASM in browsers, edge runtimes, Deno, and Bun.

Reproduce it yourself: cargo run --release -p datalogic-bench --bin compare β€” full matrix and caveats in tools/benchmark/BENCHMARK.md.


Engine guarantees

  • Conformance, enforced in CI β€” passes the official JSONLogic suite plus an extended cross-binding battery: 1,565 cases across 54 suites, run against the same core every binding ships.
  • 59 built-in operators β€” comparison, arithmetic, logic, strings, arrays, datetime, error handling; extensible with custom operators authored per host language.
  • Thread-safe evaluation β€” compiled Logic is Send + Sync; share it across threads via Arc.
  • Zero unsafe β€” the core engine forbids unsafe code (#![forbid(unsafe_code)]).
  • Zero-copy variables β€” bumpalo-backed evaluation; read-through operations like var borrow directly from the input.
  • Serde-optional β€” the default build has no serde_json dependency; enable the feature only for typed interop.
  • Configurable semantics β€” division-by-zero behavior, NaN handling, truthiness rules, and numeric coercions are all engine options.
  • Verifiable supply chain β€” npm packages publish from GitHub Actions with provenance attestation; check with npm audit signatures.

OpenFeature / flagd

The opt-in flagd cargo feature (enabled in every language binding) ships the fractional and sem_ver operators used by OpenFeature flagd flag definitions. fractional implements murmurhash3 bucketing byte-compatible with the canonical Go evaluator, so users land in the same variant buckets across implementations. That makes the engine usable as an in-process, flagd-compatible feature-flag evaluator in all eight runtimes.


Migrating from v4

v5 contains breaking API updates: DataLogic is renamed to Engine, CompiledLogic to Logic, and Operator to CustomOperator. One-shot evaluation now uses eval_str (returning a String) or eval_into::<T> (for typed values). The npm WASM package moved from @goplasmatic/datalogic to @goplasmatic/datalogic-wasm. See MIGRATION.md for the step-by-step guide.


Resources


Who is using datalogic-rs?

  • dataflow-rs (Plasmatic) β€” workflow/rules automation engine; every route condition is a compiled datalogic rule.
  • datafake-rs (Plasmatic) β€” mock JSON data generator configured with JSONLogic expressions.

Running datalogic-rs in production? Add your project β€” a one-line PR or issue is enough.


Contributing

See CONTRIBUTING.md for contribution rules, DEVELOPMENT.md for environment setup, and ARCHITECTURE.md for structural diagrams. Questions and ideas are welcome in Discussions.

About Plasmatic

Created by Plasmatic, building open-source tools for financial infrastructure and data processing.

License

Licensed under Apache 2.0. See LICENSE for details.