Define your schema in TypeScript, push it from the CLI, and protect routes with a single decorator. One config file feeds your app, your scripts, and your CI — with no .perm drift to maintain.
.perm file to keep in sync.PermifyModule, mark a controller with @CheckPermission(), and the guard handles AND / OR evaluation for you.permify.config.ts is the single source of truth. Your runtime, the CLI, and your tests all read the same file.createPermifyClient() wires connectivity. checkPermission() and writeRelationships() hide the stubs.Skip the .perm file. defineConfig gives you typed entities, relations, and permission expressions in the same project as your app code.
import { defineConfig, schema, entity, relation, permission } from "@permify-toolkit/core"; export default defineConfig({ tenant: "t1", client: { endpoint: "localhost:3478", insecure: true }, schema: schema({ user: entity({}), document: entity({ relations: { owner: relation("user"), viewer: relation("user") }, permissions: { edit: permission("owner"), view: permission("viewer or owner"), }, }), }), });
$ permify-toolkit schema push ✓ Pushed schema · tenant="t1" · v=17 $ permify-toolkit relationships seed \ --file ./data/relationships.json ✓ Seeded 42 relationships in 240ms $ permify-toolkit schema diff ~ document · permission "view" - owner + viewer or owner
No flags for tenants, endpoints, or auth tokens — the CLI reads your config. diff shows you what's about to change before you run push.
Add @CheckPermission() with the resource, action, and a function to extract the resource id. The guard does the rest.
@Get(":id") @UseGuards(PermifyGuard) @CheckPermission({ resource: "document", action: "view", resourceId: (req) => req.params.id, }) findOne(@Param("id") id: string) { return this.documentsService.findOne(id); }
The schema DSL, a typed Permify client, and a shared config loader. Use this on its own if you don't run NestJS.
A NestJS module, a guard, and the @CheckPermission() decorator with AND / OR logic.
Schema push, relationship seeding, and a few other chores. Reads the same permify.config.ts.
Originally built to stop re-writing the same Permify wiring across NestJS projects. Open source, MIT, and shaped by issues from people using it.
"Permify is great, but using it from a Node app often ends up being more work than it should be. permify-toolkit is what I wish I had from the start."— Nikhil · author