react-permission-gate
v0.1.0
Published
Flexible, type-safe permission management for React and React Router applications
Maintainers
Readme
react-permission-gate
Flexible, type-safe permission management for React and React Router applications.
Features
- Pure TypeScript core — use
PermissionCheckeranywhere, no React needed - React integration —
PermissionProvider,usePermissionshook,PermissionGatecomponent - React Router integration —
ProtectedRoutewith redirect support - Admin bypass — configurable admin role types that skip all checks
- Type-safe permission constants —
createPermissions()with literal types - Tree-shakeable — separate entry points, import only what you need
Installation
npm install react-permission-gateQuick Start
1. Define your permissions (optional but recommended)
import { createPermissions } from "react-permission-gate";
export const PERMISSIONS = createPermissions({
USERS: {
READ: "system.users.read",
CREATE: "system.users.create",
DELETE: "system.users.delete",
},
GROUPS: {
READ: "system.groups.read",
},
});2. Wrap your app with PermissionProvider
import { PermissionProvider } from "react-permission-gate/react";
function App() {
const { user, isLoading } = useAuth(); // your auth hook
return (
<PermissionProvider
permissions={user?.permissions ?? []}
userType={user?.role}
loading={isLoading}
>
<Router />
</PermissionProvider>
);
}3. Use PermissionGate in components
import { PermissionGate } from "react-permission-gate/react";
function UsersPage() {
return (
<div>
<h1>Users</h1>
<PermissionGate permission={PERMISSIONS.USERS.CREATE}>
<button>Create User</button>
</PermissionGate>
<PermissionGate
anyOf={[PERMISSIONS.USERS.CREATE, PERMISSIONS.USERS.DELETE]}
fallback={<span>No access</span>}
>
<AdminPanel />
</PermissionGate>
</div>
);
}4. Use usePermissions hook
import { usePermissions } from "react-permission-gate/react";
function UserActions() {
const { hasPermission, isAdmin } = usePermissions();
if (!hasPermission(PERMISSIONS.USERS.DELETE)) return null;
return <button>Delete User</button>;
}5. Protect routes
import { ProtectedRoute } from "react-permission-gate/react-router";
<Route
path="/users"
element={
<ProtectedRoute
permission={PERMISSIONS.USERS.READ}
redirectTo="/unauthorized"
loadingComponent={<Spinner />}
>
<UsersPage />
</ProtectedRoute>
}
/>API Reference
Core (react-permission-gate)
PermissionChecker
Pure TypeScript permission checker class.
const checker = new PermissionChecker({
permissions: ["users.read", "users.create"],
userType: "USER",
adminTypes: ["ADMIN"], // default: ["ADMIN"]
adminBypass: true, // default: true
});
checker.hasPermission("users.read"); // true
checker.hasAnyPermission(["a", "b"]); // boolean
checker.hasAllPermissions(["a", "b"]); // boolean
checker.check("users.read"); // { granted: true, reason: "permission_found" }
checker.admin; // booleancreatePermissions(definition)
Creates a deeply frozen, type-safe permission constants object.
const PERMS = createPermissions({
USERS: { READ: "users.read" },
});
// typeof PERMS.USERS.READ → "users.read" (literal type)React (react-permission-gate/react)
<PermissionProvider>
| Prop | Type | Default | Description |
|---|---|---|---|
| permissions | string[] | required | User's permission strings |
| userType | string | "" | User's type/role |
| adminTypes | string[] | ["ADMIN"] | Types that bypass all checks |
| adminBypass | boolean | true | Whether admin bypass is enabled |
| loading | boolean | false | External loading state |
usePermissions()
Returns: { permissions, userType, isAdmin, isLoading, hasPermission, hasAnyPermission, hasAllPermissions, check }
<PermissionGate>
| Prop | Type | Default | Description |
|---|---|---|---|
| permission | string | - | Single required permission |
| anyOf | string[] | - | Show if user has any |
| allOf | string[] | - | Show if user has all |
| fallback | ReactNode | null | Shown when denied |
React Router (react-permission-gate/react-router)
<ProtectedRoute>
| Prop | Type | Default | Description |
|---|---|---|---|
| permission | string | - | Single required permission |
| anyOf | string[] | - | Access if user has any |
| allOf | string[] | - | Access if user has all |
| redirectTo | string | "/" | Redirect on denied |
| loadingComponent | ReactNode | null | Shown while loading |
Admin Bypass
By default, users with userType: "ADMIN" bypass all permission checks. Configure via:
<PermissionProvider
permissions={user.permissions}
userType={user.role}
adminTypes={["ADMIN", "SUPER_ADMIN"]} // custom admin types
adminBypass={false} // disable bypass entirely
>License
MIT
