โจ
Composable
Build complex permissions from simple rules with or, and, not operators
๐
Type-safe
Full TypeScript inference with generic contexts and resources
โก
Async-first
Works seamlessly with databases, APIs, and DataLoader batching
๐ง
Framework-agnostic
Works with Express, Hono, Next.js, GraphQL, React, and more
๐ชถ
Zero dependencies
Lightweight and performant with no external dependencies
๐งช
Easy to test
Pure functions make permissions simple to test and debug
Quick Example
import { permission, or } from 'granter';
// Define permissions
const isAdmin = permission('isAdmin', (ctx) => 
  ctx.user.role === 'admin'
);
const isPostOwner = permission('isPostOwner', (ctx, post) => 
  post.authorId === ctx.user.id
);
// Compose permissions
const canEditPost = or(isPostOwner, isAdmin);
// Use them
if (await canEditPost(ctx, post)) {
  await updatePost(post);
}
// Or throw if not allowed
await canEditPost.orThrow(ctx, post);Installation
npm install granter