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

@chord-ts/rebac

v0.0.10

Published

The onward way to use ReBAC systems in TypeScript

Readme

🎣 Chord - ReBAC

The onward way to use ReBAC (relation-based access control) systems in TypeScript with sweet syntax

tuple.developer('<ID>').uses.framework('@chord-ts/rebac')

This library provides a fluent and intuitive API for interacting with a ReBAC system.

📚 Table of Contents

  • 🚀 Usage
    • Initialization
    • Creating Relationships
    • Checking Permissions (can)
    • Listing Permissions (what...canDo)
    • Querying Subjects (who)
    • Querying Entities (where)
    • Deleting Entities
  • 🛠️ Development
  • ⚖️ License

🚀 Usage

Below are examples of how to use the main features, based on the library's test suite.

Initialization

First, you need to initialize the ReBAC client with an adapter. This example uses the Permify adapter.

You'll need to define your entity types, relations, and permissions.

import { ReBAC } from '../src'
import { Permify } from '../src/adapters'
import { grpc } from '@permify/permify-node'
import 'dotenv/config'

// Define your schema types
type Entities = 'user' | 'project'
type Relations = 'admin' | 'manager'
type Permissions = 'delete' | 'edit' | 'invite'

// 1. Setup Permify client
const client = grpc.newClient(
  {
    endpoint: process.env.PERMIFY_HOST!,
    insecure: true,
  },
  grpc.newAccessTokenInterceptor(process.env.PERMIFY_API_TOKEN!),
)
// 2. Configure ReBAC client
const tenantId = 'testing'
// You should fetch the latest schema version for your tenant
const schemaVersion = await client.schema.list({ tenantId }).then((r) => r.head)
const metadata = { schemaVersion, depth: 20 }

// 3. Create the ReBAC client instance
const rebac = new ReBAC<Entities, Relations, Permissions>(
  new Permify(client, tenantId, metadata),
)

Creating Relationships

Relationships, or "tuples", define who has what kind of access to which resource. You can create tuples with a fluent API and persist them using connect.

A tuple follows the structure: subject -> relation -> entity.

// Create relationship tuples
const tuple1 = rebac.tuple.user('1').admin.project('1')
const tuple2 = rebac.tuple.user('2').manager.project('1')

// Persist the relationships in your ReBAC system
await rebac.connect(tuple1, tuple2)

The tuple builder creates a plain object that represents the relationship, which is then used by the adapter.

const tuple = rebac.tuple.user('1').admin.project('1')

/*
console.log(tuple) will output:
{
  subject: { type: 'user', id: '1' },
  relation: 'admin',
  entity: { type: 'project', id: '1' },
  permission: 'admin',
  attrs: [],
  entryPoint: 'TUPLE',
}
*/

Checking Permissions (can)

To check if a subject has a specific permission on an entity, use the can builder.

// Does user '1' have 'delete' permission on project '1'?
// (Assuming the schema grants 'delete' to 'admin')
const hasAccess = await rebac.can.user('1').delete.project('1')
// hasAccess -> true

// Does user '2' have 'delete' permission on project '1'?
// (Assuming the schema does NOT grant 'delete' to 'manager')
const hasNoAccess = await rebac.can.user('2').delete.project('1')
// hasNoAccess -> false

Listing Permissions (what...canDo)

You can retrieve all the permissions a subject has on a specific entity.

// What can user '1' do on project '1'?
const permissions = await rebac.what.user('1').canDo.project('1')

/*
permissions might look like this:
{
  delete: true,
  edit: true,
  invite: true,
  admin: true,
  manager: false,
}
*/

Querying Subjects (who)

To find out which subjects have a certain permission on an entity, use the who builder.

// Who can 'delete' project '1'?
const usersWithDelete = await rebac.who.project('1').delete.user()
// usersWithDelete -> ['1']

// Who can 'invite' to project '1'?
// (Assuming both 'admin' and 'manager' can 'invite')
const usersWithInvite = await rebac.who.project('1').invite.user()
// usersWithInvite -> ['1', '2']

Querying Entities (where)

To find out which entities of a certain type a subject has a permission on, use the where builder.

// On which projects can user '1' 'edit'?
const editableProjects = await rebac.where.user('1').edit.project()
// editableProjects -> ['1']

Deleting Entities

You can delete entities from your ReBAC system. This will remove the entity and all relationships associated with it.

// Define entity references
const userEntity = rebac.entity.user('1')
const projectEntity = rebac.entity.project('1')

// Delete the entities
const { success } = await rebac.delete(userEntity, projectEntity)
// success -> true

🛠️ Development

  • Install dependencies:
pnpm install
  • Run the unit tests:
pnpm test
  • Build the library:
pnpm build

⚖️ License

Apache 2.0 License © 2025 Dmitriy Din