Table of Contents
- The Before/After That Will Blow Your Mind
- We've All Been Here
- The Magic Moment That Changed Everything
- Try This Right Now (30 Seconds)
- Three Superpowers That Will Change Your Life
- Your Real-World Use Cases
- Framework? We Don't Care About Your Framework
- The Challenge: I Dare You To Try This
- The Proof Is In The Pudding
- Your Next 5 Minutes
The Before/After That Will Blow Your Mind 😶🌫️
// ❌ BEFORE: 100+ lines of spaghetti code nightmare
function canUserAccessResource(user, resource, order) {
if (!user) return false;
if (!user.active) return false;
if (user.status === 'banned' || user.status === 'suspended') return false;
if (!user.emailVerified) return false;
if (user.age < 18) return false;
if (user.role === 'admin') return true;
if (user.role === 'user') {
if (!user.permissions || !Array.isArray(user.permissions)) return false;
if (!user.permissions.includes('read')) return false;
if (resource.sensitivity === 'high') {
if (!user.permissions.includes('sensitive_data')) return false;
if (user.clearanceLevel < 3) return false;
}
if (order && order.total > 1000) {
if (user.accountAge < 30) return false;
if (!user.verifiedIdentity) return false;
}
if (user.department !== resource.department) {
if (!user.crossDepartmentAccess) return false;
}
// ... 60+ more lines of nested conditions
}
return false;
}
// ✅ AFTER: 5 clean, readable lines with Rule Engine JS
const accessRule = rules.and(
rules.validation.activeUser('user'),
rules.gte('user.age', 18),
rules.or(
rules.eq('user.role', 'admin'),
rules.and(
rules.in('read', 'user.permissions'),
rules.departmentAccess('user', 'resource')
)
)
);
const canAccess = engine.evaluate(accessRule, { user, resource, order });
What if I told you this messy business logic that's killing your codebase could be 5 readable lines instead?
We've All Been Here 🫂
Picture this: It's Friday afternoon. The product manager slides into your DMs with those dreaded words: "Hey, can you just add one tiny condition to the user access logic?"
You open the file. 200 lines of nested if
statements stare back at you. Comments from 3 different developers. Business logic scattered across 7 different functions. You die a little inside.
Sound familiar? 😭
Every developer has that one function. You know the one:
- Started as "simple user validation"
- Now handles 47 different edge cases
- Nobody wants to touch it
- Breaks every time someone sneezes
- Takes 30 minutes to understand what it actually does
The Magic Moment That Changed Everything
Here's what made me build Rule Engine JS. I was working on an e-commerce platform when the business team dropped this bomb:
"We need to update discount rules every week without deploying code."
That's when it hit me: What if business logic could live in the database as simple JSON?
// Store rules as JSON in your database
const discountRule = {
"or": [
{
"and": [
{"eq": ["customer.type", "vip"]},
{"gte": ["order.total", 100]}
]
},
{"gte": ["customer.loyaltyPoints", 1000]},
{
"and": [
{"eq": ["customer.isFirstTime", true]},
{"gte": ["order.total", 50]}
]
}
]
};
// Business team updates rules WITHOUT touching code
await updateRule('discount-eligibility', newRules);
// Your app instantly uses the new logic
const result = engine.evaluate(loadedRule, customerData);
Zero deployments. Zero downtime. Zero developer headaches.
Try This Right Now (30 Seconds)
npm install rule-engine-js
import { createRuleEngine, createRuleHelpers } from 'rule-engine-js';
const engine = createRuleEngine();
const rules = createRuleHelpers();
// Test it with the alcohol purchase rule
const canBuyAlcohol = rules.gte('age', 21);
console.log(engine.evaluate(canBuyAlcohol, { age: 25 })); // true
console.log(engine.evaluate(canBuyAlcohol, { age: 19 })); // false
// Your first "holy shit" moment starts now
That's it. No configuration. No setup. Just working code.
Three Superpowers That Will Change Your Life
🔥 Superpower 1: Dynamic Field Comparison
Most rule engines make you jump through hoops to compare fields. We make it natural:
// Compare ANY fields in your data
const orderValidation = rules.and(
rules.field.lessThan('order.total', 'user.creditLimit'),
rules.field.equals('password', 'confirmPassword'),
rules.field.greaterThan('user.accountAge', 'security.minimumAge')
);
// Works with nested objects automatically
const profileCheck = rules.field.equals('user.email', 'backup.recoveryEmail');
Other rule engines: "Write custom validators and hope they work"
Rule Engine JS: "Just tell us what to compare"
⚡ Superpower 2: Zero Dependencies + Lightning Fast
// Bundle size: 24KB (smaller than most images)
// Evaluation time: <1ms (faster than a database query)
// Dependencies: 0 (your security team will love you)
// Node.js versions: 16+ (just works everywhere)
Your app stays lean. Your builds stay fast. Your deploys stay simple.
🛡️ Superpower 3: Production-Ready Security
We handle the nightmare scenarios so you don't have to:
// Built-in protection against:
// ✅ Prototype pollution attacks
// ✅ Code injection attempts
// ✅ DoS attacks via complex rules
// ✅ Function execution exploits
// This malicious input fails safely:
const maliciousData = {
__proto__: { isAdmin: true },
constructor: { prototype: { hasAccess: true } }
};
engine.evaluate(rule, maliciousData); // Secure, no exploits possible
Sleep better knowing your rule engine isn't a security hole.
Your Real-World Use Cases
Form Validation That Doesn't Suck
const formRules = rules.and(
rules.validation.required('email'),
rules.validation.email('email'),
rules.field.equals('password', 'confirmPassword'),
rules.validation.ageRange('age', 18, 120),
rules.isTrue('agreedToTerms')
);
// One rule handles your entire form
const isValid = engine.evaluate(formRules, formData);
User Access Control (The Clean Way)
const accessRule = rules.and(
rules.isTrue('user.active'),
rules.or(
rules.eq('user.role', 'admin'),
rules.and(
rules.eq('user.department', 'resource.department'),
rules.in('read', 'user.permissions')
)
)
);
// Express middleware in 3 lines
app.get('/sensitive-data', (req, res, next) => {
const hasAccess = engine.evaluate(accessRule, { user: req.user, resource });
hasAccess ? next() : res.status(403).json({ error: 'Access denied' });
});
Dynamic Pricing (Without The Headache)
const pricingRule = rules.or(
// VIP discount
rules.and(
rules.eq('customer.tier', 'vip'),
rules.gte('order.total', 100)
),
// Loyalty discount
rules.gte('customer.points', 1000),
// First-time customer
rules.and(
rules.isTrue('customer.firstTime'),
rules.gte('order.total', 50)
)
);
// Business team updates pricing rules via admin panel
// Zero developer involvement
Framework? We Don't Care About Your Framework
React? ✅ Perfect
Vue? ✅ Works great
Express? ✅ Love it
Next.js? ✅ No problem
Vanilla JS? ✅ Obviously
Your weird internal framework? ✅ Probably fine
// React component
function UserProfile({ user }) {
const canEdit = engine.evaluate(editRule, { user, currentUser });
return (
<div>
<h1>{user.name}</h1>
{canEdit && <button>Edit Profile</button>}
</div>
);
}
// Vue computed property
computed: {
userCanAccess() {
return engine.evaluate(this.accessRule, this.userData);
}
}
// Express middleware
const checkAccess = (rule) => (req, res, next) => {
engine.evaluate(rule, req.user) ? next() : res.status(403).end();
};
The Challenge: I Dare You To Try This
Here's my challenge: Take your messiest business logic function. The one that makes junior developers cry. The one with 47 nested conditions.
Time yourself:
- ⏱️ 5 minutes to install Rule Engine JS
- ⏱️ 10 minutes to rewrite that function as rules
- ⏱️ Watch your code become readable for the first time in months
I bet you'll:
- Cut your code by 60-80%
- Actually understand what the logic does
- Want to rewrite every other business rule in your app
- Wonder why you didn't do this years ago
The Proof Is In The Pudding
// Before: 47 lines, 6 nested levels, 3 bugs, 0 tests
function canUserDoThing(user, thing, context) {
// ... 47 lines of hell
}
// After: 8 lines, readable, testable, maintainable
const canDoThingRule = rules.and(
rules.validation.activeUser('user'),
rules.or(
rules.eq('user.role', 'admin'),
rules.and(
rules.in('thing.permission', 'user.permissions'),
rules.field.greaterThan('user.level', 'thing.requiredLevel')
)
)
);
const result = engine.evaluate(canDoThingRule, { user, thing, context });
Same logic. 85% less code. 100% more sanity.
Your Next 5 Minutes
Ready to stop hating your business logic?
⭐ Star the repo: github.com/crafts69guy/rule-engine-js (seriously, this helps)
🚀 Try it now: npm install rule-engine-js
📚 Read the docs: Complete examples and patterns included
💬 Tell me your story: What business logic nightmare did you solve? I want to hear about your wins!
🐛 Found an issue? Open a GitHub issue - I actually respond to them
Built by a developer who was tired of business logic spaghetti. Zero dependencies, maximum developer happiness.
P.S. - If you're still writing 100-line business logic functions in 2024, your future self will thank you for making the switch. Trust me on this one.
I seriously do not see how this is any more useful than writing the if/else logic.
You have to learn new syntax for some wrapper function.
You have to install it via npm
You will have to update it as it changes, probably at some point causing some conflict with some other terribly useless npm lib
It doesn't save you any time.
In fact, you have to learn more stuff to use it, so it's gonna slow you down more.