A headless, pure TypeScript permission engine. Define actions with condition functions, inject context server-side via handlers, and extend with plugins (role, whitelist, ownership, audit, etc.). Same philosophy as better-auth — but for permissions.
bun add @better-permission/coreimport { betterPermission } from "@better-permission/core";
const engine = betterPermission({
actions: {
"user:delete": (ctx) => ({
allowed: ctx.user?.roles?.includes("admin") ?? false,
reason: ctx.user?.roles?.includes("admin") ? "admin" : "forbidden",
}),
},
});
const result = await engine.evaluate("user:delete", { user: { id: "u1", roles: ["admin"] } });
// { allowed: true, reason: "admin" }| Package | Description |
|---|---|
@better-permission/core |
Engine, addAction, evaluate, routes |
@better-permission/types |
PermissionContext, EvaluationResult |
@better-permission/errors |
PermissionDeniedError, ActionNotFoundError |
@better-permission/handler-hono |
Hono bridge |
@better-permission/handler-express |
Express bridge |
@better-permission/adapter-memory |
In-memory adapter for dev/E2E |
@better-permission/plugin-role |
Role-based permissions |
@better-permission/plugin-whitelist |
Case-by-case whitelist |
bun install
bun run test
bun run lint
bun run typecheckMIT — see LICENSE
See CONTRIBUTING.md