the-rule-engine
v1.0.0
Published
⚙️ A small fluent DSL for conditional logic (validation, gating, etc)
Maintainers
Readme
⚙️ the-rule-engine
"Declarative. Readable. Chainable. Unreasonably good looking."
the-rule-engine is a lightweight, fluent API for building business logic, conditional flows, validations, or feature gating — without writing spaghetti if (a && (b || !c)) messes.
It's your very own rule DSL – ideal for settings where rules might get complicated, but your brain shouldn't have to.
🧩 Use Cases
- ✅ Feature gating (A/B testing, roles, regions)
- ✅ Form validation logic
- ✅ Dynamic pricing tiers
- ✅ Content access control
- ✅ Rule-based UI rendering
- ✅ Complex conditional branching
🦾 Why use the-rule-engine?
- 🧠 Fluent DSL: Read like English. Write like code.
- 🧼 Zero boilerplate: No ASTs, no config, no YAML dragons.
- 🧪 Fully testable: Tiny API surface, easy mocks, clean logic.
- 🧩 Composable: Use sub-engines or group logic like a pro.
- 🔁 Negations & nesting: Yes, we support
.notGroup(...).
🚀 Installation
npm install the-rule-engine🧑💻 Usage
import { createRuleEngine } from 'the-rule-engine';
const engine = createRuleEngine()
.when(user => user.age >= 18)
.and(user => user.country === 'US')
.notGroup(group =>
group.when(user => user.banned).or(user => user.status === 'inactive')
)
.then(() => '✅ Access Granted')
.otherwise(() => '❌ Access Denied');
console.log(engine.evaluate({
age: 22,
country: 'US',
banned: false,
status: 'active'
})); // ✅ Access Granted🧠 API Overview
| Method | Description |
| ------------------------ | -------------------------------------------- |
| when(fn) | Entry condition (if). Starts rule chain. |
| and(fn) | Adds AND condition to current logic chain. |
| or(fn) | Adds OR condition. |
| not(fn) | Negates a condition. |
| group(cb) | Nest AND conditions inside a callback. |
| orGroup(cb) | Nest OR group of rules. |
| andGroup(cb) | Explicit AND group. |
| notGroup(cb) | Nest rules and negate the group result. |
| then(fn) | What to do if the rules pass. |
| otherwise(fn) | What to do if rules fail. |
| evaluate(ctx) | Evaluate against input data. |
| evaluateLogicOnly(ctx) | Returns only boolean result. |
💡 Real-World Example
const engine = createRuleEngine()
.when(u => u.role === 'admin')
.orGroup(g =>
g.when(u => u.plan === 'pro').and(u => u.paid === true)
)
.not(u => u.suspended)
.then(() => '🚀 Dashboard Access')
.otherwise(() => '🔒 Please upgrade');
engine.evaluate({ role: 'user', plan: 'pro', paid: true, suspended: false });
// → 🚀 Dashboard Access🧪 Testing
npm run testAll examples from the README are covered in the test suite, including:
- 🧱 Basic rules
- 🔁 Nesting & grouping
- 🔀 Multiple logic paths
- ❗ Negations
- 🧼 Clean evaluation with return value or boolean
🗿 Philosophy
- Simplicity over frameworks.
- Logic should be readable by humans, not just parsed by AI.
- One chain to rule them all.
🐾 Related Inspiration
- Redux-style DSLs (
.map().reduce()) - Rule-based access control (RBAC)
- Business logic extractors
- Decision trees (without looking like one)
📦 CommonJS + ESM support
// ESM
import { createRuleEngine } from 'the-rule-engine';
// CommonJS
const { createRuleEngine } = require('the-rule-engine');🧘 Final Thoughts
Use it for fun, profit, or clarity.
If your logic starts to look like:
if (a && (!b || (c && !d))) { ... }It's time for the-rule-engine.
Made with ☕ + 😤 to avoid if-else spaghetti.
🧑🚀 About the Developer
Built by cinfinit who’s:
Written too many if/else blocks to count
Thought, “There has to be a cleaner way”
Refused to let business logic live in nested ternaries
Drinks water like .then() drinks callbacks
They don’t claim to be a 10x engineer — just someone who believes logic should be elegant, readable, and maybe even fun.
Feel free to open issues, contribute, or just send memes about ugly conditionals.
