You already write Prisma on the server. Now write it in the browser.
A Prisma generator that creates a type-safe IndexedDB client with the API you already know — plus an optional sync engine that handles conflict resolution, ownership, and offline-first data for you.
Documentation · Live Demo · npm
Even with the idb library, querying across relations means manual index lookups, joins in application code, and zero type safety:
const db = await openDB("MyDB", 1);
const posts = await db.getAllFromIndex("posts", "byAuthor", userId);
const result = [];
for (const post of posts) {
if (!post.published) continue;
const comments = await db.getAllFromIndex("comments", "byPost", post.id);
result.push({ ...post, comments });
}
result.sort((a, b) => b.createdAt - a.createdAt);
// manual joins, no types, no filteringPrisma IDB:
const posts = await idb.post.findMany({
where: { authorId: userId, published: true },
include: {
comments: { orderBy: { createdAt: "desc" } },
},
orderBy: { createdAt: "desc" },
});Same API as Prisma Client. Fully typed. Works offline.
Most IndexedDB libraries stop at CRUD. This one includes a bidirectional sync engine that handles the hard parts:
generator prismaIDB {
provider = "idb-client-generator"
output = "./prisma-idb"
outboxSync = true // ← one flag
rootModel = "User"
}- Outbox pattern — mutations queue locally, push reliably with retry and batching
- Ownership DAG — authorization is structural, every record traces back to its owner
- Conflict resolution — server-authoritative changelog materialization on pull
pnpm add idb
pnpm add @prisma-idb/idb-client-generator --save-devAdd the generator to your schema.prisma:
generator prismaIDB {
provider = "idb-client-generator"
output = "./prisma-idb"
}
model Todo {
id String @id @default(cuid())
title String
done Boolean @default(false)
}pnpm exec prisma generateimport { PrismaIDBClient } from "./prisma-idb";
const idb = await PrismaIDBClient.createClient();
// Create
await idb.todo.create({
data: { title: "Ship it", done: false },
});
// Read
const todos = await idb.todo.findMany({
where: { done: false },
});
// Update
await idb.todo.update({
where: { id: todoId },
data: { done: true },
});
// Delete
await idb.todo.delete({
where: { id: todoId },
});- Prisma-compatible API —
create,findMany,findUnique,update,delete,upsert, and more - Full type safety — generated from your Prisma schema with complete autocomplete
- Relations —
includeandselectwork as expected - Offline-first — all data in IndexedDB, zero network dependency
- Optional sync — bidirectional server sync with conflict resolution and authorization
- Client-generated IDs —
cuidoruuid, no server round-trip for creates
Contributions welcome. See CONTRIBUTING.md.
See SECURITY.md for reporting vulnerabilities.
MIT. See LICENSE.
Prisma is a trademark of Prisma. Prisma IDB is an independent open-source project, not affiliated with or endorsed by Prisma.