Some releases are expensive for reasons unrelated to code. Mobile stores and mini-app platforms add review time. Desktop clients may update slowly. Even on the web, a full deployment can be a large blast radius for changing one threshold.
Remote rules can separate a business decision from the client release cycle. The useful phrase is can separate. Doing it safely requires more than putting JSON behind an endpoint.
A small example
import { createRuleEngine, createRuleHelpers } from "rule-engine-js";
type PromotionContext = { user: { age: number; verified: boolean }; order: { total: number };};
const engine = createRuleEngine();const rules = createRuleHelpers<PromotionContext>();
const fallbackRule = rules.and( rules.gte("user.age", 18), rules.eq("user.verified", true), rules.gte("order.total", 50),);
const result = engine.evaluateExpr(fallbackRule, context);The rule is data, so a compatible replacement can be fetched without rebuilding the app. The client still needs a known-good fallback.
Treat the rule response as a contract
A remote payload should include more than an expression:
{ "id": "promotion-eligibility", "version": 17, "schemaVersion": 1, "effectiveAt": "2026-09-04T00:00:00Z", "expression": { "and": [ { "gte": ["user.age", 18] }, { "eq": ["user.verified", true] }, { "gte": ["order.total", 50] } ] }}The client should reject unsupported schema versions, invalid operators, excessive complexity, and payloads outside their validity window. Cache only a validated rule.
If fetching fails, choose the fallback based on risk:
- eligibility for a cosmetic promotion may fail closed or use the bundled rule;
- security and payment decisions should be enforced by the server;
- stale rules should have an explicit maximum age;
- a last-known-good rule should never be overwritten by an invalid response.
Roll out rules like releases
A rule change skips an app rebuild, but it is still a production change. Give it the same basics:
- validate against a schema;
- replay representative and boundary fixtures;
- evaluate in shadow mode when possible;
- activate for a small cohort;
- watch decision rates and errors by version;
- keep one-click rollback.
A/B tests should assign a stable cohort on the server and record both the experiment and rule versions. Otherwise support teams cannot explain why two users received different results.
Keep the authority clear
Client evaluation is useful for immediate UI feedback and offline behavior. It is not proof that an operation is allowed. A modified client can ignore the rule entirely.
For discounts, access control, fraud checks, or regulated decisions, send the same versioned context to the server and make the authoritative decision there. The client can be optimistic; the backend must be correct.
rule-engine-js v1.0.7 provides typed rule helpers, safe nested path resolution, caching, metrics, and stateful evaluation. Those features solve evaluation. Distribution, approval, compatibility, and rollback remain application concerns.
Sources: rule-engine-js repository, npm package.
