- Notifications
You must be signed in to change notification settings - Fork97
Fullstack TypeScript toolkit that enhances Prisma ORM with flexible Authorization layer for RBAC/ABAC/PBAC/ReBAC, offering auto-generated type-safe APIs and frontend hooks.
License
zenstackhq/zenstack
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
ZenStack is a Node.js/TypeScript toolkit that simplifies the development of web applications. It enhancesPrisma ORM with a flexible Authorization layer and auto-generated, type-safe APIs/hooks, unlocking its full potential for full-stack development.
Our goal is to let you save time writing boilerplate code and focus on building real features!
Read full documentation at 👉🏻zenstack.dev. JoinDiscord for feedback and questions.
ZenStack incrementally extends Prisma's power with the following four layers:
ZenStack introduces a data modeling language called "ZModel" - a superset of Prisma schema language. It extended Prisma schema with custom attributes and functions and, based on that, implemented a flexible access control layer around Prisma.
// base.zmodelabstractmodelBase{idString @idauthorUser @relation(fields:[authorId],references:[id])authorIdString// 🔐 allow full CRUD by author @@allow('all',author==auth())}
// schema.zmodelimport"base"modelPostextendsBase{titleStringpublishedBoolean @default(false)// 🔐 allow logged-in users to read published posts @@allow('read',auth()!=null&&published)}
Thezenstack
CLI transpiles the ZModel into a standard Prisma schema, which you can use with the regular Prisma workflows.
At runtime, transparent proxies are created around Prisma clients for intercepting queries and mutations to enforce access policies.
import{enhance}from'@zenstackhq/runtime';// a regular Prisma clientconstprisma=newPrismaClient();asyncfunctiongetPosts(userId:string){// create an enhanced Prisma client that has access control enabledconstenhanced=enhance(prisma,{user:userId});// only posts that're visible to the user will be returnedreturnenhanced.post.findMany();}
Server adapter packages help you wrap an access-control-enabled Prisma client into backend CRUD APIs that can be safely called from the frontend. Here's an example for Next.js:
// pages/api/model/[...path].tsimport{requestHandler}from'@zenstackhq/next';import{enhance}from'@zenstackhq/runtime';import{getSessionUser}from'@lib/auth';import{prisma}from'@lib/db';// Mount Prisma-style APIs: "/api/model/post/findMany", "/api/model/post/create", etc.// Can be configured to provide standard RESTful APIs (using JSON:API) instead.exportdefaultrequestHandler({getPrisma:(req,res)=>enhance(prisma,{user:getSessionUser(req,res)}),});
Plugins can generate strong-typed client libraries that talk to the aforementioned APIs. Here's an example for React:
// components/MyPosts.tsximport{useFindManyPost}from'@lib/hooks';constMyPosts=()=>{// list all posts that're visible to the current user, together with their authorsconst{data:posts}=useFindManyPost({include:{author:true},orderBy:{createdAt:'desc'},});return(<ul>{posts?.map((post)=>(<likey={post.id}>{post.title} by{post.author.name}</li>))}</ul>);};
The following diagram gives a high-level architecture overview of ZenStack.
- Access control and data validation rules right inside your Prisma schema
- Auto-generated OpenAPI (RESTful) specifications, services, and client libraries
- End-to-end type safety
- Extensible: custom attributes, functions, and a plugin system
- A framework-agnostic core with framework-specific adapters
- Uncompromised performance
- Prisma schema generator
- Zod schema generator
- SWR andTanStack Query hooks generator
- OpenAPI specification generator
- tRPC router generator
- 🙋🏻Request for a plugin
- Custom attributes and functions
- Multi-file schema and model inheritance
- Polymorphic Relations
- Strongly typed JSON field
- Field encryption
- 🙋🏻Request for an extension
Thesample repo includes the following patterns:
- ACL
- RBAC
- ABAC
- Multi-Tenancy
You can usethis blog post as an introduction.
Check out theMulti-tenant Todo App for a running example. You can find different implementations below:
- Next.js + NextAuth + TanStack Query
- Next.js + NextAuth + SWR
- Next.js + NextAuth + tRPC
- Nuxt + TanStack Query
- SvelteKit + TanStack Query
- RedwoodJS
- Next.js + App Route + TanStack Query
- Next.js + Pages Route + SWR
- Next.js + App Route + tRPC
- Nuxt + TanStack Query
- SvelteKit
- Remix
- NestJS Backend API
- Express Backend API
- Clerk Integration
Join ourdiscord server for chat and updates!
If you like ZenStack, join us to make it a better tool! Please use theContributing Guide for details on how to get started, and don't hesitate to joinDiscord to share your thoughts. Documentations reside in a separate repo:zenstack-docs.
Please also considersponsoring our work to speed up the development. Your contribution will be 100% used as a bounty reward to encourage community members to help fix bugs, add features, and improve documentation.
Thank you for your generous support!
Suhyl | Marblism | Mermaid Chart | CodeRabbit | Johann Rohn |
Benjamin Zecirovic | Ulric | Fabian Jocks |
Thanks to all the contributors who have helped make ZenStack better!
About
Fullstack TypeScript toolkit that enhances Prisma ORM with flexible Authorization layer for RBAC/ABAC/PBAC/ReBAC, offering auto-generated type-safe APIs and frontend hooks.