Tiny, zero-dependency ACL utility for string-based permissions. Keep your access rules in plain JSON, load them into memory, and ask one simple question: “does this subject have this permission?”
- Minimal surface area:
ACL.add,ACL.grants,ACL.toJSON. - Works with any permission strings; no enums or magic constants.
- Ships with TypeScript definitions for IntelliSense without changing your code.
- Stateless persistence: serialize to JSON, store anywhere, hydrate back.
npm install quick-aclimport { ACL } from "quick-acl";
// Seed from JSON (e.g., database, file, KV)
const acl = new ACL([
{ sub: "user-123", permissions: ["read", "write"] },
{ sub: "service-api", permissions: ["read"] },
]);
// Check access
if (acl.grants("user-123", "write")) {
// do the thing
}
// Mutate at runtime
acl.add({ sub: "auditor", permissions: ["read", "export"] });
// Persist for later
const snapshot = acl.toJSON(); // plain JSON arraynew ACL(documents?: AccessDocumentJSON[])create an ACL from existing JSON (defaults to empty).add(document: AccessDocumentJSON)add or replace a subject’s permissions.grants(subject: string, action: string): booleanreturnstruewhen the permission exists.toJSON(): AccessDocumentJSON[]serialize for storage or transport.
AccessDocumentJSONis{ sub: string; permissions: string[] }. Permissions are free-form strings—use any naming that fits your system.
Type definitions live in types/index.d.ts and are wired via the package exports. Both JavaScript and TypeScript consumers get autocompletion for ACL out of the box; no extra config required.
npm testnpm run benchBenchmarks use the built-in benchmarks/bench.js script. They measure adds, lookups, and serialization on a representative dataset; adjust sizes inside the script to match your workload.
- No validation or normalization of permission names—bring your own conventions.
- In-memory by design; persistence is your responsibility via
toJSON(). - Explicitly minimal: no roles, hierarchies, or conditionals. Compose those on top if you need them.