A production-grade React authorization framework for RBAC, PBAC, ABAC, feature flags, and async permission checks
npm install react-auth-gateA production-grade React authorization framework that centralizes RBAC, PBAC, ABAC, feature flags, and async permission checks into a clean, declarative API.
Permission logic never lives inside components again.



๐ Documentation โข ๐ฎ Live Demo
---
- ๐ฏ Declarative API - Gate components with simple props
- ๐ RBAC + PBAC + ABAC - Role, Permission, and Attribute-based access control
- โก Async Support - Check permissions against APIs in real-time
- ๐ฉ Feature Flags - Built-in feature flag support
- ๐จ Framework Agnostic - Works with any React app (Next.js, CRA, Vite, etc.)
- ๐ฆ Tree-shakeable - Zero runtime overhead for unused features
- ๐ TypeScript First - Fully typed with excellent IntelliSense
- ๐ ๏ธ Dev Tools Panel - Killer feature: Automatic permission debugging panel in development
- ๐ชถ Lightweight - No heavy dependencies
---
``bash`
npm install react-auth-gate
`tsx
import { PermissionsRoot, PermissionsGate } from 'react-auth-gate';
// 1. Define your permission rules
const rules = {
'user.edit': ({ user, resource }) =>
user.role === 'admin' || user.id === resource.id,
'post.delete': ({ user, resource }) =>
user.id === resource.authorId,
};
// 2. Wrap your app
function App() {
return (
roles={['editor']}
permissions={['post.create', 'post.edit']}
rules={rules}
flags={{ newUI: true }}
>
);
}
// 3. Use permission gates anywhere
function UserProfile({ user }) {
return (
That's it! Your permissions are centralized, testable, and declarative.
---
๐ Core Concepts
$3
Rules are functions that determine access. They receive a context object and return a boolean (or Promise).
`tsx
type PermissionRule = (ctx: {
user: any; // Current user
resource?: any; // Resource being accessed
roles: string[]; // User's roles
permissions: string[]; // User's permissions
flags: Record; // Feature flags
}) => boolean | Promise;
`$3
#### 1. Role-Based (RBAC)
`tsx
const rules = {
'admin.access': ({ roles }) => roles.includes('admin'),
};
`#### 2. Permission-Based (PBAC)
`tsx
const rules = {
'post.create': ({ permissions }) => permissions.includes('post.create'),
};
`#### 3. Attribute-Based (ABAC)
`tsx
const rules = {
'user.edit': ({ user, resource }) =>
user.role === 'admin' || user.id === resource.id,
};
`#### 4. Async Rules
`tsx
const rules = {
'subscription.premium': async ({ user }) => {
const subscription = await checkSubscriptionAPI(user.id);
return subscription.isPremium;
},
};
`---
๐ฏ API Reference
$3
The root provider component. Use this to wrap your app with automatic dev tools integration.
`tsx
user={currentUser}
roles={['admin', 'editor']}
permissions={['post.edit', 'post.delete']}
rules={rulesMap}
flags={{ newUI: true }}
enableDevTools={true} // default: auto-enabled in development
>
`Props:
-
user - Current authenticated user
- roles? - Array of role strings
- permissions? - Array of permission strings
- rules? - Map of named permission rules
- flags? - Feature flags object
- enableDevTools? - Enable/disable dev panel (default: auto in dev mode)---
$3
Declarative permission boundary component.
`tsx
allow="user.edit"
resource={user}
mode="hide"
fallback={Access Denied}
>
`Props:
-
allow? - Permission check (string, array, or function)
- any? - Array of permissions (OR logic)
- all? - Array of permissions (AND logic)
- resource? - Resource to check against
- mode? - "hide" (default) or "disable"
- fallback? - React node to show when denied
- children - Protected contentExamples:
`tsx
// Single permission
// Multiple permissions (any)
// Multiple permissions (all)
// Disable mode
// Inline rule
user.verified}>
// With fallback
}>
`---
$3
Hook for programmatic permission checks.
`tsx
const { allowed, loading } = usePermission('user.edit', user);return (
);
`Returns:
-
allowed - Boolean indicating if permission is granted
- loading - Boolean indicating if check is in progressSimpler version (no loading state):
`tsx
const canEdit = usePermissionValue('user.edit', user);
`---
$3
Render-prop version for maximum control.
`tsx
{(allowed, loading) => (
)}
`---
$3
Route protection component (framework-agnostic).
`tsx
// React Router
path="/admin"
element={
allow="admin.access"
fallback={ }
>
}
/>// Next.js
function AdminPage() {
const router = useRouter();
return (
allow="admin"
onAccessDenied={() => router.push('/login')}
>
);
}
`Props:
-
allow - Permission check
- resource? - Resource to check
- fallback? - Content when denied (default: unauthorized message)
- onAccessDenied? - Callback when access denied
- children - Protected content---
๐ ๏ธ Dev Tools Panel (The Killer Feature)
In development mode, react-auth-gate automatically renders a floating permission debugger.
$3
โ
Live Permission Tracking - See every permission check as it happens
โ
Pass/Fail Details - Understand why checks succeed or fail
โ
Rule Inspection - See which rules evaluated and their results
โ
Context Override - Test different roles, permissions, and flags
โ
Real-time Simulation - Toggle permissions without code changes
โ
Zero Configuration - Appears automatically when using
PermissionsRoot$3
1. Use
PermissionsRoot instead of PermissionsProvider
2. Run your app in development mode
3. Click the ๐ icon in the bottom-right corner$3
1. Evaluations
- Shows all permission checks in real-time
- Pass/fail status with rule details
- Timestamps and evaluation duration
- Resource information
2. Overrides
- Toggle roles on/off
- Add/remove permissions
- Enable/disable feature flags
- Test different scenarios instantly
3. Context
- View current user object
- See active roles and permissions
- Inspect feature flags
- Debug context values
๐ Common Patterns
$3
`tsx
const rules = {
'resource.edit': ({ user, resource }) =>
user.role === 'admin' || user.id === resource.ownerId,
};
`$3
`tsx
const rules = {
'event.register': ({ resource }) => {
const now = Date.now();
return now >= resource.registrationStart && now <= resource.registrationEnd;
},
};
`$3
`tsx
const rules = {
'content.view': ({ permissions }) =>
permissions.includes('content.view') ||
permissions.includes('content.edit') ||
permissions.includes('content.admin'),
};
`$3
`tsx
const rules = {
'order.cancel': ({ user, resource }) => {
// Can't cancel shipped orders
if (resource.status === 'shipped') return false;
// Customer can cancel within 24h
if (user.id === resource.customerId) {
const hoursSinceOrder = (Date.now() - resource.createdAt) / (1000 60 60);
return hoursSinceOrder < 24;
}
// Admin can always cancel
return user.role === 'admin';
},
};
`---
๐งช Testing
Permission rules are pure functions, making them easy to test.
`tsx
import { rules } from './permissions';describe('user.edit permission', () => {
it('allows admin to edit any user', () => {
const result = rules'user.edit';
expect(result).toBe(true);
});
it('allows user to edit themselves', () => {
const result = rules'user.edit';
expect(result).toBe(true);
});
it('denies user from editing others', () => {
const result = rules'user.edit';
expect(result).toBe(false);
});
});
`---
๐ฆ Advanced Usage
$3
If you need custom integration without dev tools:
`tsx
import { PermissionsProvider } from 'react-auth-gate';
`$3
`tsx
import { PermissionsProvider, DevPanel, useDevRegister } from 'react-auth-gate';function Root() {
const registerEvaluation = useDevRegister();
return (
);
}
`$3
`tsx
import { evaluatePermission, createPermissionContext } from 'react-auth-gate';const context = createPermissionContext(user, resource, roles, permissions, flags);
const result = await evaluatePermission(check, context, rulesMap);
`---
๐จ TypeScript Support
Fully typed with generics for your custom types:
`tsx
interface User {
id: string;
role: 'admin' | 'user';
}interface Post {
id: string;
authorId: string;
}
const rules: PermissionRulesMap = {
'post.edit': ({ user, resource }) => {
// Full type safety!
return user.role === 'admin' || user.id === resource?.authorId;
},
};
`---
๐ง Framework Integration
$3
`tsx
import { ProtectedRoute } from 'react-auth-gate';
import { Navigate } from 'react-router-dom'; path="/admin"
element={
}>
}
/>
`$3
`tsx
// pages/admin.tsx
import { ProtectedRoute } from 'react-auth-gate';
import { useRouter } from 'next/router';export default function AdminPage() {
const router = useRouter();
return (
allow="admin"
onAccessDenied={() => router.push('/login')}
>
);
}
`$3
`tsx
import { ProtectedRoute } from 'react-auth-gate';
import { useNavigate } from '@remix-run/react';export default function Route() {
const navigate = useNavigate();
return (
allow="admin"
onAccessDenied={() => navigate('/login')}
>
);
}
`---
๐ค FAQ
Q: How is this different from checking permissions in components?
A: All permission logic is centralized in the rules map. Components don't contain authorization logic, making them easier to maintain and test.
Q: Can I use this with server-side auth?
A: Yes! This library handles UI-level authorization. Your server should still validate permissions. This prevents unnecessary API calls and provides better UX.
Q: Does this work with Next.js App Router?
A: Yes! Use
"use client" for components using the library. Server Components can check permissions differently.Q: What about bundle size?
A: ~5KB gzipped. Tree-shakeable, so you only pay for what you use.
Q: Can I use this without TypeScript?
A: Yes, but TypeScript is recommended for the best experience.
Q: How do I disable the dev panel in production?
A: It's automatically disabled when
process.env.NODE_ENV === 'production'.---
๐ฏ Best Practices
1. โ
Centralize rules - Define all rules in one place
2. โ
Keep rules pure - No side effects in rule functions
3. โ
Test rules independently - Rules are just functions
4. โ
Use TypeScript - Get type safety for users and resources
5. โ
Async sparingly - Async rules add latency
6. โ
Server-side validation - Never trust client-side checks alone
7. โ
Use the dev panel - Debug permissions visually
8. โ
Resource-based when possible - More secure than role-only checks
9. โ
Fallback content - Provide good UX when access is denied
10. โ
Name rules clearly - Use dot notation:
resource.action`---
MIT ยฉ 2024
---
Contributions are welcome! Please open an issue or PR.
---
- GitHub Repository
- npm Package
- Report Issues