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

permask

v2.1.1

Published

A lightweight utility library for managing permission bitmasks with groups and access levels

Readme

permask npm build status Download

A lightweight TypeScript library for managing permissions using bitmasks. Using just utility functions will be even smaller with tree-shaking.

What are bitmasks?

Bitmasks are a way to store multiple boolean values in a single integer. They are useful for managing permissions, flags or groups.

For example in UNIX file systems, bitmasks are used to manage file permissions (read, write, execute) for users, groups and others. Like 777 for full access to everyone, 755 for read and execute access to everyone, but full access to the owner.

Why use bitmasks?

  • Fast: Bitwise operations (&, |) are faster than comparing strings.
  • Compact: Combine multiple permissions in a single integer (e.g., 0b1111 for read, create, update, delete). Just 4 bits for access control. For groups, you can use any number of bits,
  • Flexible: Easy to check, add, or remove permissions.

Example of using bitmasks:

const READ = 1;   // 0b0001
const CREATE = 2;  // 0b0010
const UPDATE = 4; // 0b0100
const DELETE = 8; // 0b1000

const userPermissions = READ | CREATE | UPDATE; // 0b0111
const canRead = (userPermissions & READ) === READ;     // true
const canCreate = (userPermissions & CREATE) === CREATE;   // true
const canUpdate = (userPermissions & UPDATE) === UPDATE; // true
const canDelete = (userPermissions & DELETE) === DELETE; // false

Bitmask in permask structure

[ Group (0–29 bits) | Permissions (4 bits) ]

  0b0001_0111 = 23
    \__/ \__/
     /     \
Group(1)  Permissions(read, create, update)

Installation

Install permask:

# npm
npm install permask
# pnpm
pnpm add permask
# yarn
yarn add permask

🎮 Playground

Try out permask interactively! Live Demo

How to use permask?

1. Define groups of permissions:

// examples
// with object
const PermissionGroup = {
  POST: 1,
  COMMENT: 2,
  LIKE: 3
} as const;

2. Initialize permask

import { createPermask } from "permask";
import { PermissionGroup } from "./permission-group"; // your defined groups

const permask = createPermask(PermissionGroup);

3. Use it

  • create a bitmask from an object:

const bitmask2 = permask.create({
  group: "LIKE",
  read: true,
  create: false,
  update: true,
  delete: false
});
console.log(bitmask2); // 53 (0b110101)
  • parse a bitmask to an object:

const parsed = permask.parse(31); // 0b11111
console.log(parsed);
// {
//   group: 1,
//   groupName: "POST",
//   read: true,
//   create: true,
//   update: true,
//   delete: true
// }
  • check if a bitmask has a specific group:

const hasGroup = permask.hasGroup(23, "LIKE");
console.log(hasGroup); // true
// You can also use numeric group IDs
const hasGroupById = permask.hasGroup(23, PermissionGroup.LIKE);
  • check if a bitmask has a specific permission:

const canRead = permask.canRead(17);
const canCreate = permask.canCreate(17);
const canDelete = permask.canDelete(17);
const canUpdate = permask.canUpdate(17);
console.log(canRead, canCreate, canDelete, canUpdate); // true, false, false, false
  • check if a bitmask has access to a specific group and permission:

import { PermissionAccess } from "permask";

// Check if bitmask has read access to LIKE group using string access
const hasReadAccess = permask.hasAccess(53, "LIKE", "read");
console.log(hasReadAccess); // true

// Check if bitmask has create access to LIKE group using string access
const hasCreateAccess = permask.hasAccess(53, "LIKE", "create");
console.log(hasCreateAccess); // false

// You can also use numeric group IDs with string access
const hasAccessById = permask.hasAccess(53, PermissionGroup.LIKE, "update");
console.log(hasAccessById); // true

// You can use numeric access values (PermissionAccess) instead of strings
const hasUpdateAccessNumeric = permask.hasAccess(53, PermissionGroup.LIKE, PermissionAccess.UPDATE);
console.log(hasUpdateAccessNumeric); // true
  • get group name from bitmask:

const groupName = permask.getGroupName(23);
console.log(groupName); // "LIKE"
const groupName2 = permask.getGroupName(29);
console.log(groupName2); // undefined

Bonus:

You can use permask just with bitmask utility functions.

But it will be without some types dependent on your groups.

Use bitmask utilities:

Functions:

  • createBitmask({ group: number, read: boolean, create: boolean, delete: boolean, update: boolean }): number - creates a bitmask from an options.

  • parseBitmask(bitmask: number): { group: number, read: boolean, create: boolean, delete: boolean, update: boolean } - parses a bitmask and returns an object.

  • getPermissionGroup(bitmask: number): number - returns a group number from a bitmask.

  • getPermissionAccess(bitmask: number): number - returns an access number from a bitmask.

  • hasPermissionGroup(bitmask: number, group: number): boolean - checks if a bitmask has a specific group.

  • hasPermissionAccess(bitmask: number, access: number): boolean - checks if a bitmask has a specific access.

  • hasRequiredPermission(bitmasks: number[], group: number, access: number): boolean - checks if any bitmask in the array has the required permission for the specified group and access.

    useful functions:

    • canRead(bitmask: number): boolean
    • canCreate(bitmask: number): boolean
    • canDelete(bitmask: number): boolean
    • canUpdate(bitmask: number): boolean
  • setPermissionGroup(bitmask: number, group: number): number - sets a group in a bitmask (will overwrite the previous group).

  • setPermissionAccess(bitmask: number, access: number): number - sets access in a bitmask (will overwrite the previous access).

  • getPermissionBitmask(group: number, access: number): number - creates a bitmask from a group and access.

  • packBitbasks(bitmasks: number[], urlSafe?: boolean): string - packs bitmasks to base64 string. (more compact than JSON.stringify)

  • unpackBitmasks(base64: string, urlSafe?: boolean): number[] - unpacks bitmasks from a base64 string.

Constants:

  • PermissionAccess - an enum-like object with access types.
    const PermissionAccess = {
        READ: 1,    // 0b0001
        CREATE: 2,   // 0b0010
        UPDATE: 4,  // 0b0100
        DELETE: 8   // 0b1000
    } as const;
  • PermissionAccessBitmasks - full access bitmask for usual cases.
    const PermissionAccessBitmasks = {
        FULL: 0b1111,  // read, create, update, delete
        CREATE: 0b0011, // read, create
        READ: 0b0001   // read-only
    } as const;

Integration with frameworks

How I'm using it?

I'm using permask in my projects to manage permissions for users. It's easy to use and understand. And that's why I decided to share it with you.

For example, I'm storing bitmask permissions array in access tokens for users. It's easy to check if user has access to a specific functionality or group.

It's possible to store ~820 bitmask permissions(1 group + 3 access) in 1kB. In JS - 128 bitmasks, because each number in JS weights 4bytes

With strings like Posts.Read, Users.Create it will be just ~35 permissions (1 group + 1 access)

Enjoy!

If you have any questions or suggestions, feel free to open an issue or pull request.

Roadmap

  • [x] Create a library
  • [x] Add tests
  • [x] Add documentation
  • [ ] Add easy-to-use integration with frameworks
    • [x] Express
    • [ ] Fastify
    • [ ] H3
    • [ ] Nitro
    • [ ] NestJS
    • [ ] Hono
    • [ ] Koa
    • [ ] itty-router

License

MIT

Copyright (c) 2025 by Dmytro Shevchenko