Step 1: Generator Config
Configure the Prisma IDB generator for sync
Step 1: Configure the Generator
Before implementing sync, you need to configure the Prisma IDB generator in your schema.prisma file. This tells the generator which models to sync and how to scope the data.
Configuration Options
Add the generator block to your prisma/schema.prisma:
generator prismaIDB {
provider = "idb-client-generator"
output = "./prisma-idb"
// Enable sync capabilities
outboxSync = true
// Anchor model for the ownership DAG
rootModel = "User"
// Models to exclude from sync (optional)
exclude = ["Session", "Verification", "Account"]
}Required Settings
outboxSync = true: Enables the bidirectional sync engine. Without this, the generated client will be read-only.rootModel: The primary entity that acts as the anchor for all other models. This must be a model in your schema that represents the data owner (typicallyUser).
Schema Constraints
All syncable models must use client-generated IDs and single ID fields. This is a fundamental requirement for the sync system to work correctly:
- Required: Use
@id @default(uuid())or@id @default(cuid())for all models included in sync - Forbidden: Composite
@@id([...])keys are not supported for syncable models. Auto-incrementing IDs with@id @default(autoincrement())are not supported for syncable models - Reason: Client-generated single-field IDs ensure that records created offline can be synchronized without ID conflicts and enable proper ownership tracking
Example of correct schema with client-generated IDs:
model User {
id String @id @default(uuid()) // ✅ Client-generated UUID
name String
}
model Post {
id String @id @default(cuid()) // ✅ Client-generated CUID
userId String
user User @relation(fields: [userId], references: [id])
}Example of incorrect schema with auto-increment:
model User {
id Int @id @default(autoincrement()) // ❌ NOT supported for sync
name String
}Optional Settings
exclude: Array of model names to skip during client generation. Use this for:- Authentication models (
Session,Account,Verification) - Server-only models that shouldn't be synced to clients
- Large or temporary tables
- Authentication models (
The Changelog model is automatically excluded and reserved for internal sync infrastructure. You don't need to
manually exclude it, though it's harmless to do so.
Scoping Rules
The rootModel and exclude settings work together to define which data gets synced:
- Only the
rootModeland its descendants (models that reference it, directly or indirectly) are synced - Excluded models are never generated in the client
- The generated client only syncs data relevant to the current user (scoped by
rootModel)
Example: Multi-User Blog
model User {
id String @id @default(cuid())
email String @unique
posts Post[]
}
model Post {
id String @id @default(cuid())
title String
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
generator prismaIDB {
provider = "idb-client-generator"
output = "./prisma-idb"
outboxSync = true
rootModel = "User"
exclude = ["AuditLog"]
}In this setup:
Useris the root modelPostsyncs because it referencesUserAuditLogis excluded and won't appear in the client
Next Steps
After configuring the generator, you need to:
- Add the
Changelogtable to your schema - Implement the push endpoint
- Implement the pull endpoint
- Initialize the sync worker on the client
Continue to Step 2: Changelog Schema.