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

react-access-engine

v1.0.0

Published

Unified access control for React & Node.js — RBAC, ABAC, feature flags, A/B experiments, plan gating, policy engine, remote config. Works with Next.js, Express, Fastify. SSR-safe, tree-shakeable, zero dependencies. One hook, one component.

Downloads

481

Readme

react-access-engine

Unified access control for React.js/Next.js — RBAC, ABAC, feature flags, experiments, plan gating, and policy engine.

One hook. One component. Everything you need.

Also works on Node.js/Express — same config, same logic, no extra package.

React.js, Next.js, Node.js, Express, RBAC, ABAC, authorization, permissions, feature flags, A/B testing, plan gating, remote config, SSR-safe, TypeScript

npm version minzipped size CI codecov TypeScript

Documentation · Playground · GitHub


Why?

React apps cobble together homegrown RBAC, a feature flag service, ad-hoc plan gating, and manual A/B test wiring each with its own provider, API, and blind spots.

react-access-engine replaces all of them with one system:

const { can, is, has, tier } = useAccess();

can('edit'); // check permission
is('admin'); // check role
has('dark-mode'); // check feature flag
tier('pro'); // check plan

Features

  • RBAC — Multi-role users, role → permission mapping, wildcard permissions
  • ABAC — Attribute-based policies with allow/deny rules and custom condition operators
  • Feature Flags — Boolean toggles, percentage rollouts, role/plan/environment targeting
  • A/B Experiments — Deterministic variant assignment, SSR-safe hashing
  • Plan Gating — Hierarchical subscription tiers with automatic comparison
  • Remote Config — Fetch config from API with stale-while-revalidate, polling, signature verification
  • Condition Engine — Declarative ABAC with built-in operators (equals, in, greaterThan, etc.)
  • Plugin System — Lifecycle hooks for audit logging, analytics, custom operators
  • DevTools — Optional overlay for inspecting access decisions in real time
  • Type Safety — Full TypeScript inference — InferRoles, InferPermissions, InferFeatures
  • SSR-Ready — Deterministic evaluation, works with Next.js App Router
  • Tree-Shakeable — Import only what you use — unused engines are eliminated at build time
  • Backend Support — Same engine functions work in Node.js/Express — no separate package needed
  • Zero Dependencies — No runtime dependencies beyond React

Installation

npm install react-access-engine

Requires react >= 18 as a peer dependency.

Quick Start

1. Define your config

import { defineAccess } from 'react-access-engine';

const config = defineAccess({
  roles: ['viewer', 'editor', 'admin'],
  permissions: {
    viewer: ['articles:read'],
    editor: ['articles:read', 'articles:write'],
    admin: ['*'],
  },
  plans: ['free', 'pro', 'enterprise'],
  features: {
    'dark-mode': true,
    'ai-assist': { enabled: true, allowedPlans: ['pro', 'enterprise'] },
    'beta-editor': { rolloutPercentage: 25 },
  },
});

2. Wrap your app

import { AccessProvider } from 'react-access-engine';

function App() {
  return (
    <AccessProvider config={config} user={{ id: 'u1', roles: ['editor'], plan: 'pro' }}>
      <YourApp />
    </AccessProvider>
  );
}

3. Use it

One hook — useAccess() — does everything:

import { useAccess } from 'react-access-engine';

function Dashboard() {
  const { can, is, has, tier } = useAccess();

  return (
    <div>
      {can('articles:write') && <button>New Article</button>}
      {is('admin') && <AdminPanel />}
      {has('dark-mode') && <DarkTheme />}
      {tier('pro') && <AIAssistant />}
    </div>
  );
}

Or use <Allow> — one component for all access control:

import { Allow } from 'react-access-engine';

function StorePage() {
  return (
    <>
      {/* Permission gate */}
      <Allow permission="articles:write" fallback={<ReadOnlyView />}>
        <Editor />
      </Allow>

      {/* Role gate */}
      <Allow role="admin">
        <AdminTools />
      </Allow>

      {/* Feature flag gate */}
      <Allow feature="dark-mode">
        <DarkTheme />
      </Allow>

      {/* Plan gate with upgrade prompt */}
      <Allow plan="pro" fallback={<UpgradePrompt />}>
        <ProFeatures />
      </Allow>

      {/* Combine conditions */}
      <Allow permission="analytics:view" plan="pro" match="all">
        <AnalyticsDashboard />
      </Allow>
    </>
  );
}

More React Examples

ABAC — resource-level access:

import { Can } from 'react-access-engine';

// Seller can only edit their own products
<Can perform="products:edit" on={{ sellerId: product.sellerId }}>
  <button>Edit Product</button>
</Can>

// Support can only refund recent orders
<Can perform="orders:refund" on={{ orderedAt: order.createdAt }}>
  <button>Process Refund</button>
</Can>

Feature flags:

import { Feature } from 'react-access-engine';

<Feature name="live-chat" fallback={<EmailSupport />}>
  <LiveChat />
</Feature>;

A/B experiments:

import { Experiment, useExperiment } from 'react-access-engine';

// Declarative
<Experiment
  id="checkout-redesign"
  variants={{ control: <CheckoutA />, redesign: <CheckoutB /> }}
  fallback={<CheckoutA />}
/>;

// Hook-based
function Checkout() {
  const { variant } = useExperiment('checkout-layout');
  return variant === 'single-page' ? <OnePageCheckout /> : <MultiStepCheckout />;
}

Plan gating with upgrade prompt:

import { usePlan } from 'react-access-engine';

function AIRecommendations() {
  const { hasPlanAccess } = usePlan();

  if (!hasPlanAccess('pro')) {
    return <UpgradeBanner plan="pro" />;
  }
  return <AIPanel />;
}

API Reference

Config

  • defineAccess — Create a fully typed access configuration
  • mergeConfigs — Merge base config with overrides (remote patches)

Components

  • AccessProvider — Context provider — wraps your app
  • Allow — Universal gate — permission, role, feature, plan
  • Can — Permission gate with ABAC resource support
  • Feature — Feature flag gate
  • Experiment — A/B test variant renderer
  • AccessGate — Multi-condition gate with mode (all/any)
  • PermissionGuard — Route-level guard requiring all permissions
  • FeatureToggle — Render-prop variant of Feature

Hooks

  • useAccess() — All-in-one access checking (can, is, has, tier)
  • usePermission(perm, resource?) — Check a single permission
  • useRole() — Role checking utilities
  • useFeature(name) — Check a feature flag with reason
  • usePolicy(perm, resource?) — Evaluate policy rules
  • useExperiment(id) — Get experiment assignment
  • usePlan() — Subscription plan checks
  • useAccessDebug() — Debug metadata (when debug: true)
  • useRemoteConfig(base, loader) — Remote config with SWR pattern

Engines & Utilities

  • RemoteConfigEngine — Programmatic remote config with polling & SWR
  • DebugEngine — Event recording for devtools integration
  • evaluateCondition / evaluateConditions — Evaluate ABAC conditions
  • buildConditionContext — Build context from user/resource/env
  • AccessContext — React Context for advanced integrations

Backend / Node.js

All engine functions are pure logic — no React dependency. Use the same config on your server:

import {
  hasPermission,
  hasRole,
  evaluateFeature,
  evaluatePolicy,
  assignExperiment,
  hasPlanAccess,
} from 'react-access-engine';

// Works in Express, Fastify, Deno, or any JS runtime
if (hasPermission(user, 'articles:read', config)) {
  /* allow */
}
if (evaluateFeature('ai-assist', user, config).enabled) {
  /* feature on */
}
if (hasPlanAccess(user, 'pro', config)) {
  /* plan ok */
}

Express middleware example:

function requirePermission(...perms: string[]) {
  return (req, res, next) => {
    for (const perm of perms) {
      if (!hasPermission(req.user, perm, config)) {
        return res.status(403).json({ error: `Permission denied: ${perm}` });
      }
    }
    next();
  };
}

app.get('/api/articles', requirePermission('articles:read'), (req, res) => {
  res.json({ articles: getAllArticles() });
});

app.delete('/api/articles/:id', requirePermission('articles:delete'), (req, res) => {
  const article = getArticleById(req.params.id);
  const policy = evaluatePolicy('articles:delete', req.user, config, { resource: article });
  if (policy.effect === 'deny') {
    return res.status(403).json({ error: 'Policy denied', reason: policy.reason });
  }
  deleteArticle(req.params.id);
  res.json({ message: 'Deleted' });
});

All backend exports:

  • RoleshasRole, hasAnyRole, hasAllRoles
  • PermissionshasPermission, hasAnyPermission, hasAllPermissions, getPermissionsForUser
  • FeaturesevaluateFeature, evaluateAllFeatures
  • PoliciesevaluatePolicy
  • ExperimentsassignExperiment
  • PlanshasPlanAccess, getPlanTier
  • ConditionsevaluateCondition, evaluateConditions, buildConditionContext
  • ClassesPluginEngine, DebugEngine

See the full backend docs for shared config patterns, feature-gated endpoints, plan guards, ABAC policy evaluation, A/B experiments, and plugin usage on Node.js.

Plugin Factories

  • createAuditLoggerPlugin — Drop-in audit logging plugin
  • createAnalyticsPlugin — Analytics event tracking plugin
  • createOperatorPlugin — Register custom condition operators

Type Inference Helpers

import type {
  InferRoles,
  InferPermissions,
  InferFeatures,
  InferPlans,
  InferExperiments,
} from 'react-access-engine';

type Roles = InferRoles<typeof config>; // 'viewer' | 'editor' | 'admin'
type Perms = InferPermissions<typeof config>; // 'articles:read' | 'articles:write' | '*'

Advanced Usage

See the full documentation for details on:

  • ABAC Policies — Composable allow/deny rules with resource conditions
  • Percentage Rollouts — Deterministic feature rollouts based on user ID hashing
  • Feature Dependencies — Features that require other features to be enabled
  • Remote Config — Fetch & merge config from API with polling and signature verification
  • Condition Engine — Declarative ABAC with built-in operators (equals, in, greaterThan, etc.)
  • Plugin System — Audit logging, analytics, custom operators
  • Experiments — A/B testing with deterministic variant assignment
  • SSR / Next.js — Works with App Router, no client-only APIs in core

DevTools

Install the companion devtools package for a development overlay:

npm install -D react-access-engine-devtools
import { AccessDevtools } from 'react-access-engine-devtools';

<AccessProvider config={config} user={user}>
  <YourApp />
  <AccessDevtools />
</AccessProvider>;

License

MIT © Abhishek Verma


Changelog · Contributing · Security