Prisma IDB FaviconPrisma IDB

Kanban Example

A Svelte app using Prisma Next IDB, migrations, auth, and full bidirectional sync

The Prisma Next kanban example is a full-stack SvelteKit app: an IndexedDB client in the browser, a Postgres server, better-auth for sessions (Google OAuth and anonymous guest sign-in), and the sync engine keeping the two databases in sync per user.

Live app: next-kanban.prisma-idb.dev Source: apps/prisma-next-idb-kanban-example

What it shows

  • One schema.prisma interpreted twice — a client (IDB) projection and a server (Postgres) projection — with @@idb.exclude marking better-auth's Session, Account, and Verification tables as server-only (see Client Contracts)
  • Committed migration chains for both sides: migrations/app (IDB) and migrations-postgres/app (Postgres)
  • createManagedAutoSyncIdbClient for a singleton, race-safe, auto-migrating, sync-tracked client in one call (see Client)
  • Google + anonymous sign-in via better-auth, with the signed-in user mirrored into IDB through withoutTracking on first load
  • A SyncWorker pushing and pulling against /api/sync/push and /api/sync/pull, with createSyncServer's ownership DAG authorizing every write and read server-side (see Server)
  • A pending-sync-count badge driven by the "outboxwrite" event, and a resync on the browser's online event
  • resetDb() (the managed client's race-safe wipe) called on sign-out, so a different account on the same browser never sees a previous session's local data
  • A minimal PWA manifest and service worker so the app shell works offline after the first load

Run it

From the repository root, bring up Postgres and initialize both databases:

pnpm --filter @prisma-next-idb/kanban-example db:up
pnpm --filter @prisma-next-idb/kanban-example db:init
pnpm --filter @prisma-next-idb/kanban-example dev

For a production check:

pnpm --filter @prisma-next-idb/kanban-example check
pnpm --filter @prisma-next-idb/kanban-example build
pnpm --filter @prisma-next-idb/kanban-example test:e2e

Offline behavior

The PWA setup intentionally stays small. The service worker precaches the built app shell and static files, then caches same-origin GET requests as they are fetched.

IndexedDB data already lives on the device. Once the browser has loaded the app and installed the service worker, the kanban UI can reopen offline, keep reading and writing local data, and queue outbox events for the SyncWorker to push once the connection returns.

Where to look

FilePurpose
src/lib/prisma/schema.prismaSingle schema, source for both the IDB and Postgres contracts
src/lib/prisma/db.tsManaged, auto-migrating, sync-tracked IDB client
src/lib/server/auth.tsbetter-auth config (Google + anonymous sign-in)
src/lib/server/sync.tscreateSyncServer + createSqlSyncAdapter (@prisma-next-idb/sync-server-sql) setup
src/routes/api/sync/push/+server.tsPush endpoint — HTTP boundary around validatePush
src/routes/api/sync/pull/+server.tsPull endpoint — HTTP boundary around buildPullQueries
src/lib/stores/kanban.svelte.tsSvelte state: loads the workspace, drives the sync worker
src/service-worker.tsCaches the app shell and same-origin assets
static/manifest.webmanifestProvides the installable PWA metadata

On this page