Integrating Nodora
Read this page if you want to integrate an application, service, or tool with Nodora rule engine.
Integrating Nodora into an application comes down to two concerns: managing rules (authoring, versioning, deploying) and evaluating them at runtime. They are deliberately decoupled — compilation produces a portable artifact, and evaluation runs that artifact on whatever path needs it, including the hot path of a request.
How you wire each side up is your choice. You can self-host the entire pipeline with the open-source SDK, or you can offload management to the Nodora platform and keep the runtime in your app. Both routes share the same evaluator, so you are free to switch later.
The two halves
Management
Management covers everything that happens before a rule reaches production: writing the source, compiling it to NIR, reviewing changes, versioning artifacts, and rolling new versions out to your services.
NIR is the JSON output of the Nodora compiler. It is a plain string — you can store it in a file, database, blob storage, or any other artifact store, and ship it to runtimes that need it.
Evaluation
Evaluation is the runtime side: loading a NIR program into an evaluator and calling it with an input. It is intentionally lightweight so it can sit on a request path without becoming a latency tax — the evaluator runs in-process, with no network hop in the critical path.
The same NIR JSON works in every supported runtime (Go binary, JS/WASM, etc.), so where you evaluate is independent of where you compile.
Choosing a route
You have two integration paths. Pick based on how much of the management side you want to own.
Self-managed
With this route, you own the management pipeline:
- Author
.rulesetfiles in your repo. - Compile them — either ahead of time with
nodora compile, or at boot withcompile()from@nodora/js. - Store the resulting NIR however you prefer (alongside your code, in a database, in object storage).
- Deploy new versions through whatever process you already use for code or config.
@nodora/js ships the compiler and
evaluator as a WebAssembly module with a thin JS wrapper. It works in
Node.js, Bun, and modern browsers from a single package, and slots
cleanly into Next.js, Remix, Hono, Express, or any other JS framework.
The recommended pattern is to compile ahead of time, ship the NIR as a build artifact, and only pay the evaluator cost at runtime. See the JavaScript SDK quickstart for the full surface.
Use this route when you want full control over how rules are stored and rolled out, you already have an artifact pipeline that fits, or you do not want a runtime dependency on an external service.
Managed platform with @nodora/client
If you do not want to build the management side from the ground up, the
Nodora platform handles authoring, version
tracking, environment promotion (staging/production), and serves the
compiled NIR to your runtimes. @nodora/client is the JS package that
fetches and evaluates rules against the platform.
import { NodoraClient } from "@nodora/client";
const client = new NodoraClient({
apiKey: process.env.NODORA_API_KEY!,
env: "production",
strategy: { type: "stale-while-revalidate", ttl: 60_000 },
});
const checkout = client.ruleset("Checkout");
const result = await checkout.evaluate("IsDiscountEligible", {
total: 100,
pastCustomer: true,
});The client keeps evaluation on the hot path — it caches NIR in-process and runs the evaluator locally. With the stale-while-revalidate strategy, evaluations return immediately from cache while fresh rulesets are fetched in the background, so a published change reaches your runtimes without you redeploying.
Evaluation events are batched and flushed to the platform so you can trace what ran, with what input, and what it produced.
Use this route when you want a UI for authoring and reviewing rules, environment-aware deploys without rebuilding your app, and observability on rule evaluations without wiring it up yourself.
Mixing the two
The routes are not exclusive. The platform produces the same NIR that
@nodora/js consumes, so you can prototype with @nodora/client, then
export the NIR and self-host the evaluation, or
the other way around. The evaluator on the runtime side is identical
in both cases.