Small and fast permission engine for Rust and JS/TS
Write your access control logic like user_id == resource_owner
and let Decide handle the rest.
Decide is a local-first, scriptable and fast permission engine built in Rust, available to use in both:
- 🦀 Rust:
decide-core
crate - 📦 JavaScript/TypeScript:
decide-core
npm package
No need to hook into external SaaS platforms for basic permission logic. Just write it yourself, but better and with the safety of expression evaluation and role mapping baked in.
- ✅ Simple: Write conditions like
user_id == resource_owner
- ⚡️ Fast: Built with Rust, benchmarked for speed even at scale
- 💻 Flexible: Use JSON config, dynamic expressions, and custom roles
- 🔌 Embeddable: Works directly in both Rust and Node.js apps
- 🧠 Local: No network calls, no latency, no external APIs
import { Decide } from "decide-core/core";
const decide = new Decide({
editor: {
name: "editor",
permissions: [
{ action: "edit_post", condition: "user_id == resource_owner" }
]
}
});
const canEdit = decide.can({
id: "123",
roles: ["editor"]
}, "edit_post", {
owner_id: "123",
resource_name: "post-123",
resource_type: "post"
});
console.log(canEdit); // true
use decide_core::types::*;
use decide_core::evaluator::Decide;
fn main() {
let user = User {
id: "123".to_string(),
roles: vec!["editor".to_string()]
};
let resource = Resource {
owner_id: "123".to_string(),
resource_name: "post-123".to_string(),
resource_type: "post".to_string()
};
let decide = Decide::default().unwrap();
let result = match decide.can(&user, "edit_post", &resource) {
Ok(res) => res,
Err(_) => false,
};
println!("Can edit: {}", result); // true
}
Language | Package | Link |
---|---|---|
JavaScript / TypeScript | decide-core |
NPM Link |
Rust | decide-core |
Crates.io |
Write powerful permission logic using expressions like:
user_id == resource_owner
user_roles.contains("admin") || user_id == resource_owner
resource_type == "post" && user_roles.contains("editor")
Yes, it's powered by rhai under the hood, so your conditions are not hardcoded functions but flexible strings.
Measured from Node.js:
Checks | Time Taken |
---|---|
1 check | ~0.64ms |
100 checks | ~41ms |
10,000 checks | ~2.5s |
100,000 checks | ~18-19s |
Fast enough for real-time checks, even at scale.
MIT