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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ghazaalma/react-access-control

v0.0.2

Published

Type-safe reactive access control engine with a React 18+ adapter

Readme

React Access Control

Type-safe reactive access control engine with React 18+ adapter for managing permissions and role-based access in React applications.

✨ Features

  • 🔒 Type-safe permissions - Permissions are inferred from your role configuration
  • ⚡️ Reactive engine - Subscribe to permission changes and react to updates automatically
  • 🔁 Dynamic updates - Change roles and direct permissions at runtime
  • ⚛️ React 18+ - Built with useSyncExternalStore
  • 🧩 Framework-agnostic core - Use the core engine without React
  • 📦 ESM + CJS support - Compatible with modern and CommonJS environments
  • 🌴 Tree-shakeable - Optimized for modern bundlers
  • 🖥️ SSR compatible - Uses useSyncExternalStore and can be used in SSR applications with appropriate client/server boundaries.

📦 Installation

npm install @ghazaalma/react-access-control

🚀 Quick Start

1. Create Access Control

Define your roles and permissions:

    import { createAccessControl } from "@ghazaalma/react-access-control";

    const roles = {
        admin: ["user.create", "user.delete", "user.view"],
        editor: ["user.create", "user.view"],
        viewer: ["user.view"]
    } as const;

    const access = createAccessControl({
        roles,
        userRoles: ["viewer"]
    });

2. Check Permissions

access.can("user.create"); // false
access.can("user.view"); // true

3. Update Roles Dynamically

Roles can be changed at runtime:

access.updateRoles(["admin"]);
access.can("user.delete") // true

4. Add Direct Permissions

Users can also have permissions that are not provided by their roles.

    const access = createAccessControl({
        roles,
        userRoles: ["viewer"],
        userPermissions: ["user.create"],
    });

    access.can("user.create"); // true

⚛️ React Integration

Step 1 - Create a Typed Context

import { createAccessControl } from "@ghazaalma/react-access-control";
import { createAccessContext } from "@ghazaalma/react-access-control/react";

const roles = {
    admin: ["user.create", "user.delete", "user.view"],
    editor: ["user.create", "user.view"],
    viewer: ["user.view"]
} as const;

const access = createAccessControl({
    roles,
    userRoles: ["viewer"]
});

const { AccessProvider, useAccess } = createAccessContext<typeof roles>();

Step 2 - Wrap Your App

    <AccessProvider access={access}>
        <App />
    </AccessProvider>

Step 3 - Check Permissions in Components

function UserActions() {
    const can = useAccess();

    return(
        <>
            {can("user.view") && <p>Can view users</p>}
            {can("user.create") && <button>Create User</button>}
            {can("user.delete") && <button>Delete User</button>}
        </>)
}

🧠 How It Works

  • The core engine maintains a computed permission set based on roles and direct permissions.
  • Updates trigger the subscription system.
  • React uses useSyncExternalStore for reactive updates.
  • Subscribers are notified only when the resolved permissions actually change

🔧 API

createAccessControl(config)

Creates a new access control instance.

Config

| Field | Type | Description | | :--- | :--- | :--- | | roles | RoleConfig | Mapping of roles to permissions | | userRoles | (keyof T)[] | Current user roles | | userPermissions | readonly ExtractPermissions<T>[] (optional) | Additional direct permissions |

Returned API

access.can(permission)

Checks whether the user has a permission.

access.can("user.create");

‍‍‍‍access.getPermissions()

Returns the current resolved permissions.

access.getPermissions();

access.updateRoles(roles)

Updates the user's roles dynamically.

access.updateRoles(["admin"]);

Subscribers are notified only if the resulting permission set changes.

access.updatePermissions(permissions)

Updates the user's direct permissions.

access.updatePermissions(["user.create"]);

Subscribers are notified only if the resulting permission set changes.

access.subscribe(listener)

Subscribes to access-control changes.

The returned function can be used to unsubscribe the listener:

const unsubscribe = access.subscribe(() => {
    console.log("Permissions changed");
});

unsubscribe();

🧩 Import Structure

import { createAccessControl } from "@ghazaalma/react-access-control";
import { createAccessContext } from "@ghazaalma/react-access-control/react";

The core package can be used independently of React, while the /react entry point provides the React adapter.

📊 When to Use

  • Admin dashboards
  • SaaS role-based systems
  • Feature access and UI gating
  • Multi-tenant applications
  • Applications with dynamic permission changes

⚠️ When NOT to Use

  • Simple boolean feature flags
  • Fully static permission systems
  • Small applications without role or permission complexity

🛠️ Development

npm run dev
npm run build
npm test
npm run typecheck

🤝 Contributing

Contributions are welcome.

Please follow these guidelines:

  • Keep TypeScript strict
  • Maintain type safety
  • Avoid unnecessary abstractions
  • Prefer composable APIs
  • Add tests for new behavior

⭐️ Support

If you find this useful:

  • ⭐️ Star the repository
  • 🪄 Report issues
  • 💡 Suggest improvements