Skip to main content

The Data Layer for Modern TypeScript Applications

Intuitive data modeling, type-safe ORM, built-in access control, automatic query services, and more.

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
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/runtime';

const db = new ZenStackClient(schema, { ... });

// high-level query API
const usersWithPosts = 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.

Automatic HTTP Query Service
coming soon

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.

Next.js Example
import { NextRequestHandler } from '@zenstackhq/server/next';
import { db } from './db'; // ZenStackClient instance
import { getSessionUser } from './auth';

// callback to provide a per-request ORM client
async function getClient() {
// call a framework-specific helper to get session user
const authUser = await getSessionUser();

// return a new ORM client configured with the user,
// the user info will be used to enforce access control
return db.$setAuth(authUser);
}

// Create a request handler for all requests to this route
// All CRUD requests are forwarded to the underlying ORM
const handler = NextRequestHandler({ getClient });

export {
handler as GET,
handler as PUT
handler as POST,
handler as PATCH,
handler as DELETE,
};

Perfect Match for AI-Assisted Programming

Coherent Application Model

Coherent Application Model

With data models, relations, validation rules, and access control policies all defined in one place, LLMs can easily get a coherent understanding of the entire application.

Concise Query API

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

Slim Code Base

By deriving many crucial artifacts from the schema, ZenStack eliminates boilerplate and helps you maintain a slim code base that is easier for AI to work with.

Notes to V2 Users

ZenStack V3 has made the bold decision to remove Prisma as a runtime dependency and implement its own ORM infrastructure on top of Kysely. Albeit the cost of such a big refactor, we believe this is the right move to gain the flexibility needed to achieve the project's vision. Please read this blog post for more thoughts behind the changes.