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

@rbac/rbac

v2.1.1

Published

Blazing Fast, Zero dependency, Hierarchical Role-Based Access Control for Node.js

Readme

CircleCI npm version Tweet

  • ⏱ Lightweight
  • ⚡️Fastest RBAC (check benchmarks)
  • ️🍃low dependency

Features

  • Focused on operations
  • Scalable
  • Each role is given specific access rights for every operation
  • High granularity in assigning rights
  • Wildcard and regex support for operations
  • Optional database adapters (MongoDB, MySQL, PostgreSQL)
  • Express, NestJS and Fastify middlewares
  • Roles can be updated at runtime

Thanks

This project now uses Vite to generate the bundled output

Thanks to Karl Düüna (DeadAlready) and his awesome post on medium

Getting Started

Install

yarn add @rbac/rbac or npm install @rbac/rbac

This library is written in TypeScript and the published package ships with its declaration files for a great developer experience.

RBAC is a curried function thats initially takes an object with configurations, then returns another function that takes an object with roles, finally returns an object that holds "can" property that is a function.

You can use it in many ways, below is one of them:

Setup RBAC config

step 01

| Property | Type | Params | Default | Description | |-------------- |--------------- |------------------------------------------------------------- |--------------- |----------------------------------------- | | logger | Function | role: Stringoperation: Stringresult: Boolean | defaultLogger | Function that logs operations to console | | enableLogger | Boolean | | true | Enable or disable logger |

Creating some roles

step 02

RBAC expects an object with roles as property names.

| Property | Type | Example | Description | |---------- |-------------- |------------------------------------------------ |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | can | Array | ['products:*'] | Array of strings, list of operations that user can do, it also supports glob patterns | | when | Function, Async Function or Promise | (params , done ) => done (null , true ) | Optional Promise that should resolve in Truthy or Falsy, an async function that returns a boolean or Promise, or a Callback function that receives params and done as properties, should return done passing errors and result | | inherits | Array | ['user'] | Optional Array of strings, list of roles inherited by this role |

IMPORTANT! "when" property can be a Callback function that receives params and done, an async function that returns a boolean or Promise, or a Promise that resolves in Truthy or Falsy values. Example:
import type { Roles } from '@rbac/rbac';

interface Params {
  registered: boolean;
}

const roles: Roles<Params> = {
  supervisor: {
    can: [{ name: 'products:find', when: (params, done) => {
      // done receives error as first argument and Truthy or Falsy value as second argument
      done(null, params.registered);
    }}]
  },
  admin: {
    can: [{ name: 'products:*', when: async (params) => {
      return params.registered;
    } }]
  }
};

Check if user can do some operation

step 03

| Param | Type | Example | Description | |-------- |----------------------------------------------- |-------------------------- |---------------------------------------------------------------- | | First | String | 'admin' | Array of strings, list of operations that user can do | | Second | String, Glob (Wildcard), Regex | 'products:find' | Operation to validate | | Third | Any | {registered: true} | Optional Params that will flow to "when" callback Function |

Update roles at runtime

RBAC exposes two helpers to modify the role definition at runtime. addRole adds a new role and updateRoles merges new definitions with the existing ones.

import RBAC from '@rbac/rbac'

const base = RBAC({ enableLogger: false })({
  user: { can: ['products:find'] }
})

base.addRole('editor', { can: ['products:update'], inherits: ['user'] })
await base.can('editor', 'products:update') // true

base.updateRoles({
  user: { can: ['products:find', 'products:create'] }
})
await base.can('user', 'products:create') // true

Database adapters

RBAC exposes optional adapters to load and persist role definitions using MongoDB, MySQL or PostgreSQL. Each adapter implements the RoleAdapter interface with getRoles, addRole and updateRoles methods.

import RBAC from '@rbac/rbac'
import { MongoRoleAdapter } from '@rbac/rbac/adapters'

const adapter = new MongoRoleAdapter({
  uri: 'mongodb://localhost:27017',
  dbName: 'mydb',
  collection: 'roles'
})

const roles = await adapter.getRoles()
const rbac = RBAC()(roles)

Adapters available:

  • MongoRoleAdapter
  • MySQLRoleAdapter
  • PostgresRoleAdapter

Adapters also allow customizing the underlying table or collection column names through a columns option when creating a new instance:

const adapter = new MySQLRoleAdapter({
  table: 'roles',
  columns: { name: 'rname', role: 'rdef', tenantId: 'tid' }
})

Multi-tenant RBAC

Adapters can optionally receive a tenantId parameter to store and retrieve roles for different tenants. When omitted, the adapter falls back to a default tenant so existing single-tenant usage keeps working. Use createTenantRBAC to instantiate an RBAC instance scoped to a tenant:

import { MongoRoleAdapter, createTenantRBAC } from '@rbac/rbac';

const adapter = new MongoRoleAdapter({ uri: 'mongodb://localhost:27017', dbName: 'mydb', collection: 'roles' });

await adapter.addRole('user', { can: ['products:find'] }, 'tenant-a');

const rbacTenantA = await createTenantRBAC(adapter, 'tenant-a');
await rbacTenantA.can('user', 'products:find'); // true

Want more? Check out the examples folder.

Middlewares

RBAC also provides helper middlewares for Express, NestJS and Fastify. They make it easy to guard routes using existing role definitions.

import RBAC, { createExpressMiddleware } from '@rbac/rbac';

const rbac = RBAC({ enableLogger: false })({
  user: { can: ['products:find'] }
});

const canFindProducts = createExpressMiddleware(rbac)('products:find');

app.get('/products', canFindProducts, handler);

For NestJS and Fastify you can use createNestMiddleware and createFastifyMiddleware respectively with a similar API.

Roadmap

  • [X] Wildcard support
  • [X] Regex support
  • [X] Update roles in runtime
  • [X] Async when callbacks
  • [X] Database adapters (MongoDB, MySQL, PostgreSQL)
  • [X] Middlewares for Express, NestJS and Fastify

v2.0.0

  • Rewritten in TypeScript
  • Internal refactor focused on readability and performance
  • Added support to update roles at runtime
  • Database adapters
  • Middlewares for Express, NestJS and Fastify

Benchmarks

Run npm run bench to execute the performance suite. The script runs two end-to-end scenarios:

  • Baseline comparison – compares @rbac/rbac with AccessControl, RBAC, Easy RBAC and Fast RBAC using the default dataset.
  • Large dataset comparison – stresses the libraries with hundreds of resources, deep inheritance chains and three when flavours (callback, async function and promise).

For each scenario the suite generates detailed reports (JSON/CSV/HTML chart) under benchmarks/results/ and prints a human-readable summary (ops/sec, margins, standard deviation, samples, etc.).

$ npm run bench
RBAC Performance Comparison ops/sec: 6859456, 6193737, 4427263, ...
RBAC Performance Comparison - Large Dataset ops/sec: 3277352, 3396327, 3424089, ...

The baseline run shows @rbac/rbac leading all categories; the large dataset confirms the same behaviour when conditional checks and large permission sets come into play.

More Information

Contributing

Contributions are welcome!

  1. Build RBAC
  • Run npm install (or yarn install) to get RBAC's dependencies
  • Run npm run build to compile the library and produce the minified bundle using Vite
  1. Development mode
  • Having all the dependencies installed run yarn dev. This command will generate a non-minified version of your library and will run a watcher so you get the compilation on file change.
  1. Running the tests
  • Run yarn test
  1. Scripts
  • npm run build - produces production version of your library under the lib folder and generates lib/@rbac/rbac.min.js via Vite
  • npm run dev - produces development version of your library and runs a watcher
  • npm test - well ... it runs the tests :)
  • npm run test:watch - same as above but in a watch mode
  • npm run bench - run the benchmark suite

License

This project is under MIT License [https://opensource.org/licenses/MIT]