npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@connectaryal/rbac

v1.0.0

Published

A flexible Role-Based Access Control (RBAC) library

Downloads

340

Readme

@connectaryal/rbac

Simple, powerful Role-Based Access Control for React applications

npm version npm downloads Bundle Size License TypeScript

Stop wrestling with complex authorization. Start building features.

@connectaryal/rbac gives you production-ready permission management with zero configuration. Built specifically for React developers who want powerful authorization without the complexity.

// Just 3 lines to add permissions
<RBACProvider config={{ roles: ['editor'] }}>
  <Can permissions="edit">
    <EditButton />
  </Can>
</RBACProvider>

Get Started · Examples · Full Docs · Why not CASL?


🎯 Why @connectaryal/rbac?

The Problem

Most React apps need permission management, but existing solutions are either:

  • Too complex - Steep learning curves, verbose APIs
  • Too basic - Lack features for real-world apps
  • Not React-first - Awkward integrations, poor DX

The Solution

@connectaryal/rbac provides:

  • Simple by default - Zero config to get started, powerful when needed
  • React-first design - Hooks, components, and patterns that feel native
  • Comprehensive toolkit - 6 hooks, 7 components, everything you need
  • Type-safe - Full TypeScript support with excellent autocomplete

The Difference

| Feature | @connectaryal/rbac | CASL | Others | |---------|-------------------|------|--------| | React Integration | Built-in (6 hooks, 7 components) | Add-on (1 hook, 1 component) | Minimal | | Learning Curve | ⭐⭐⭐⭐⭐ Easy | ⭐⭐⭐ Moderate | Varies | | Setup Time | < 2 minutes | 5-10 minutes | Varies | | Multi-tenant Support | ✅ Built-in sectors | ❌ DIY | ❌ DIY | | Explicit Deny Lists | ✅ Restrictions | Via rules | Limited | | Bundle Size | ~12KB | ~8KB | Varies |


✨ Features

🎯 Simple by Default

Zero configuration required. Works out of the box with sensible defaults.

🔒 Powerful When Needed

Advanced features like sector-based restrictions, role hierarchies, and dynamic updates.

⚛️ React-First Design

Built specifically for React with hooks and components that feel natural.

🪝 6 Specialized Hooks

usePermission, useHasPermission, useCanAny, useCanAll, useIsRestricted, useRBACContext

🧩 7 Ready-Made Components

<Can>, <Cannot>, <PermissionGate>, <PermissionSwitch>, <PermissionBoundary>, <RestrictedContent>, <PermissionDebug>

🏢 Multi-Tenant Ready

Built-in sector/context system for multi-department or multi-tenant apps.

🚫 Explicit Deny Lists

Restrictions that override all permissions - perfect for compliance and security policies.

🎨 Natural Language API

Components read like English: <Can permissions="edit"> or <Cannot permissions="admin">

📊 Debug Tools

Built-in <PermissionDebug> component for development.

🔍 Full TypeScript Support

Autocomplete for permissions, roles, and sectors. Type-safe by default.


📦 Installation

npm install @connectaryal/rbac
# or
yarn add @connectaryal/rbac
# or
pnpm add @connectaryal/rbac

Peer Dependencies:

  • React ≥16.8.0 (hooks support)
  • React DOM ≥16.8.0

🚀 Quick Start

1. Basic Setup (30 seconds)

import { RBACProvider, Can } from '@connectaryal/rbac';

function App() {
  return (
    <RBACProvider config={{
      roles: ['editor'],
      roleDefinitions: {
        viewer: ['read'],
        editor: ['read', 'write'],
        admin: ['read', 'write', 'delete']
      }
    }}>
      <Dashboard />
    </RBACProvider>
  );
}

function Dashboard() {
  return (
    <div>
      <Can permissions="write">
        <button>Edit</button>
      </Can>
      <Can permissions="delete">
        <button>Delete</button>
      </Can>
    </div>
  );
}

2. Using Hooks

import { usePermission, useHasPermission } from '@connectaryal/rbac';

function Editor() {
  // Simple boolean check
  const canEdit = useHasPermission('edit');
  
  // Detailed information
  const { hasPermission, isRestricted, allPermissions } = usePermission('delete', {
    includeDetails: true
  });

  return (
    <div>
      {canEdit && <button>Edit</button>}
      {hasPermission && <button>Delete</button>}
      {isRestricted && <p>Delete is restricted by policy</p>}
    </div>
  );
}

3. Multiple Permissions

import { useCanAll, useCanAny } from '@connectaryal/rbac';

function AdminPanel() {
  // User must have ALL permissions
  const hasFullAccess = useCanAll(['read', 'write', 'delete']);
  
  // User needs at least ONE permission
  const hasAnyAccess = useCanAny(['read', 'write']);

  if (!hasFullAccess) return <LimitedAccess />;
  return <FullAdminPanel />;
}

4. Advanced: Restrictions & Sectors

import { RBACProvider } from '@connectaryal/rbac';

function App() {
  return (
    <RBACProvider config={{
      roles: ['admin'],
      sector: 'finance',
      restrictions: ['permanent_delete'], // Global restriction
      roleDefinitions: {
        admin: ['read', 'write', 'delete']
      },
      sectorRestrictions: {
        finance: ['delete', 'transfer_funds'], // Context-based
        hr: ['export_salary_data']
      }
    }}>
      <Dashboard />
    </RBACProvider>
  );
}

📚 Core Concepts

Roles

Define user roles and their associated permissions.

const config = {
  roles: ['editor', 'reviewer'],
  roleDefinitions: {
    viewer: ['read'],
    editor: ['read', 'write'],
    reviewer: ['read', 'approve'],
    admin: ['read', 'write', 'delete', 'approve']
  }
};

Direct Permissions

Grant permissions directly without roles.

const config = {
  permissions: ['special_feature', 'beta_access']
};

Restrictions (Deny Lists)

Explicitly deny permissions, overriding all grants.

const config = {
  roles: ['admin'],
  restrictions: ['delete'], // Admin cannot delete
  roleDefinitions: {
    admin: ['read', 'write', 'delete'] // Has permission...
  }
  // Result: Admin can read and write, but NOT delete (restricted)
};

Sectors (Multi-Tenant)

Context-based restrictions for different departments or tenants.

const config = {
  roles: ['manager'],
  sector: 'finance',
  roleDefinitions: {
    manager: ['read', 'write', 'delete', 'transfer']
  },
  sectorRestrictions: {
    finance: ['delete', 'transfer'], // Restricted in finance
    hr: ['export'],                  // Restricted in HR
    it: []                           // No restrictions in IT
  }
};

// Later, switch sectors:
rbac.setSector('it'); // Now delete and transfer are allowed

📖 Examples

E-commerce Dashboard

import { RBACProvider, Can, Cannot, usePermission } from '@connectaryal/rbac';

function EcommerceDashboard() {
  return (
    <RBACProvider config={{
      roles: ['manager'],
      roleDefinitions: {
        viewer: ['view_orders', 'view_products'],
        manager: ['view_orders', 'view_products', 'create_orders', 'approve_orders'],
        admin: ['view_orders', 'view_products', 'create_orders', 'approve_orders', 'delete_orders']
      }
    }}>
      <Dashboard />
    </RBACProvider>
  );
}

function Dashboard() {
  const { hasPermission } = usePermission('approve_orders');

  return (
    <div>
      <h1>Orders Dashboard</h1>
      
      <Can permissions="view_orders">
        <OrdersList />
      </Can>

      <Can permissions="create_orders">
        <button>Create New Order</button>
      </Can>

      {hasPermission && <button>Approve Pending Orders</button>}

      <Cannot permissions="delete_orders">
        <div className="alert">
          Contact admin to delete orders
        </div>
      </Cannot>
    </div>
  );
}

Multi-Department SaaS

import { RBACProvider, PermissionBoundary } from '@connectaryal/rbac';

function MultiDepartmentApp() {
  const [department, setDepartment] = useState('finance');
  
  return (
    <RBACProvider config={{
      roles: ['admin'],
      sector: department,
      roleDefinitions: {
        admin: ['read', 'write', 'delete', 'export', 'transfer']
      },
      sectorRestrictions: {
        finance: ['delete', 'transfer'],
        hr: ['export'],
        it: []
      }
    }}>
      <DepartmentSelector onChange={setDepartment} />
      <DepartmentDashboard />
    </RBACProvider>
  );
}

function DepartmentDashboard() {
  return (
    <div>
      <PermissionBoundary
        permissions="delete"
        onDenied={<div>Access Denied</div>}
        onRestricted={<div>Delete restricted in this department</div>}
      >
        <button>Delete Record</button>
      </PermissionBoundary>
    </div>
  );
}

More examples in:


🎨 Components

<Can>

Show content when user has permission.

<Can permissions="edit">
  <EditButton />
</Can>

<Can permissions={['create', 'delete']} checkType="EVERY">
  <AdminPanel />
</Can>

<Cannot>

Show content when user does NOT have permission.

<Cannot permissions="premium_features">
  <UpgradePrompt />
</Cannot>

<PermissionSwitch>

Render different content based on permission.

<PermissionSwitch
  permissions="edit"
  granted={<EditMode />}
  denied={<ViewOnlyMode />}
  loading={<Spinner />}
/>

<PermissionBoundary>

Advanced boundary with restriction detection.

<PermissionBoundary
  permissions="delete"
  onDenied={<AccessDenied />}
  onRestricted={<PolicyBlocked />}
  onDeniedCallback={() => trackEvent('access_denied')}
>
  <DeleteButton />
</PermissionBoundary>

<PermissionDebug>

Development tool to inspect permissions.

{process.env.NODE_ENV === 'development' && (
  <PermissionDebug showSummary json />
)}

See all components →


🪝 Hooks

usePermission(permissions, options)

Full-featured permission check with detailed information.

const { 
  hasPermission,      // boolean | null
  isInitialized,      // boolean
  isRestricted,       // boolean
  restrictionReason,  // 'direct' | 'sector'
  allPermissions,     // Set<Permission>
  currentSector,      // Sector | null
  can                 // (perm) => boolean
} = usePermission('write', { includeDetails: true });

useHasPermission(permissions, checkType)

Simple boolean check.

const canEdit = useHasPermission('edit');
const canManage = useHasPermission(['create', 'update', 'delete'], 'EVERY');

useCanAny(permissions)

Check if user has at least one permission.

const hasAnyAccess = useCanAny(['read', 'write']);

useCanAll(permissions)

Check if user has all permissions.

const hasFullAccess = useCanAll(['read', 'write', 'delete']);

useIsRestricted(permission)

Check if a permission is restricted.

const isDeleteRestricted = useIsRestricted('delete');

useRBACContext()

Access the RBAC instance directly.

const { rbac, isInitialized } = useRBACContext();
const summary = rbac?.getPermissionSummary();

See all hooks →


⚖️ vs CASL

Both are excellent libraries. Here's when to choose each:

Choose @connectaryal/rbac when:

✅ Building a React-only application
✅ Want simple, straightforward RBAC
✅ Need comprehensive React hooks out of the box
✅ Need multi-tenant/sector context switching
✅ Prefer explicit restriction (deny list) model
✅ Value developer experience and quick setup
✅ Need ready-made UI components

Choose CASL when:

✅ Need attribute-based permissions (check object properties)
✅ Building full-stack app (shared backend logic)
✅ Need field-level permission control
✅ Require database integration (Mongoose/Prisma)
✅ Want maximum flexibility and control
✅ Need multi-framework support (Vue, Angular, etc.)

Bottom line: @connectaryal/rbac is simpler and more React-friendly. CASL is more powerful for complex, full-stack scenarios.

Detailed comparison →


🎯 When to Use

✅ Great for:

  • React-only applications - Built for React, feels native
  • Role-based permissions - Straightforward role management
  • Multi-tenant SaaS - Sector-based restrictions
  • Admin dashboards - Rich component library
  • E-commerce platforms - Permission-gated features
  • Content management - Role-based workflows
  • Quick prototypes - Zero config, fast setup

⚠️ Consider alternatives if:

  • Need attribute-based conditions → Use CASL (check object properties)
  • Need backend integration → Use CASL (Mongoose/Prisma support)
  • Need field-level control → Use CASL (per-field permissions)
  • Building non-React app → Use framework-specific solution

📚 Documentation


🤝 Contributing

We welcome contributions! Whether it's:

  • 🐛 Bug reports
  • 💡 Feature requests
  • 📝 Documentation improvements
  • 💻 Code contributions

Please read our CONTRIBUTING.md for guidelines.


📄 License

MIT License © Shiva Aryal

See LICENSE for details.


🙏 Acknowledgments

Inspired by CASL and the React community.

Built with ❤️ for React developers who want simple, powerful authorization.


💬 Support


⭐ Show Your Support

If this project helped you, please consider giving it a ⭐ on GitHub!

It helps others discover the project and motivates continued development.