
Coherent Schema
Simple schema language to capture the most important aspects of your application in one place: data and security.

Powerful ORM
One-of-a-kind ORM that combines type-safety, query flexibility, and access control in one package.

Limitless Utility
Deriving crucial artifacts that streamline development from backend APIs to frontend components.
Used and Loved by
Intuitive and Expressive Data Modeling
The modeling language allows you to
- ✅ Define data models and relations
- ✅ Define access control policies
- ✅ Express data validation rules
- ✅ Model polymorphic inheritance
- ✅ Add custom attributes and functions to introduce custom semantics
- ✅ Implement custom code generators
The schema language is a superset of Prisma Schema Language. Migrating a Prisma schema is as simple as file renaming.
model User {
id Int @id
email String @unique @email // constraint and validation
role String
posts Post[] // relation to another model
postCount Int @computed // computed field
// access control rules colocated with data
@@allow('all', auth().id == id)
@@allow('create, read', true)
}
model Post {
id Int @id
title String @length(1, 255)
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int // relation foreign key
@@allow('read', published)
@@allow('all', auth().id == authorId || auth().role == 'ADMIN')
}
Flexible and Awesomely Typed ORM
import { schema } from './zenstack';
import { ZenStackClient } from '@zenstackhq/orm';
import { PolicyPlugin } from '@zenstackhq/plugin-policy';
const db = new ZenStackClient(schema, { ... })
// install access control plugin to enforce policies
.$use(new PolicyPlugin())
// set current user context
.$setAuth(...);
// high-level query API
const userWithPosts = await db.user.findUnique({
where: { id: userId },
include: { posts: true }
});
// low-level SQL query builder API
const userPostJoin = await db
.$qb
.selectFrom('User')
.innerJoin('Post', 'Post.authorId', 'User.id')
.select(['User.id', 'User.email', 'Post.title'])
.where('User.id', '=', userId)
.execute();
An ORM is derived from the schema that gives you
- 🔋 High-level ORM query API
- 🔋 Low-level SQL query builder API
- 🔋 Access control enforcement
- 🔋 Runtime data validation
- 🔋 Computed fields and custom procedures
- 🔋 Plugin system for tapping into various lifecycle events
ZenStack's ORM is built on top of the awesome Kysely SQL query builder. Its query API is compatible with that of Prisma Client, so migrating an existing Prisma project will require minimal code changes. Read more about migrating from Prisma.
Automatic HTTP Query Service
Thanks to the ORM's built-in access control, you get an HTTP query service for free
- 🚀 Fully mirrors the ORM API
- 🚀 Seamlessly integrates with popular frameworks
- 🚀 Works with any authentication solution
- 🚀 Type-safe client SDK powered by TanStack Query
- 🚀 Highly customizable
Since the ORM is protected with access control, ZenStack can directly map it to an HTTP service. ZenStack provides out-of-the-box integrations with popular frameworks including Next.js, Nuxt, Express, etc.
Client hooks based on TanStack Query can also be derived from the schema, allowing you to make type-safe queries to the service without writing a single line of code.
Perfect Match for AI-Assisted Programming

Single Source of Truth
When LLMs see a self-contained, non-ambiguous, and well-defined application model, their inference works more efficiently and effectively.

Concise Query API
Concise and expressive, while leveraging existing knowledge of Prisma and Kysely, the query API makes it easy for LLMs to generate high-quality query code.

Slim Code Base
By deriving artifacts from the schema instead of implementing them, ZenStack helps you maintain a slim code base that is easier for AI to digest.