A monorepo keeps all your apps and shared code in one repository. With Bun workspaces and Turborepo task orchestration, you get fast installs, parallel builds, and type-safe package sharing.
badmin
Admin panel monorepo — web + server + docs + shared packages.
cyop
AI captioning monorepo — web + server + tRPC + auth + db packages.
fullstack
Template monorepo — web + docs + desktop + API + shared packages.
The ^build syntax means “build all dependencies first.” Turborepo automatically parallelizes tasks that have no dependency between them — e.g., building packages/ui and packages/db can run simultaneously.
// packages/db/src/schema.tsexport * from "./schema/users"export * from "./schema/roles"// packages/db/src/client.tsimport { drizzle } from "drizzle-orm/better-sqlite3"import Database from "better-sqlite3"import * as schema from "./schema"const sqlite = new Database("./dev.db")export const db = drizzle(sqlite, { schema })
Both apps/server and apps/web (for server functions) import from @repo/db.
The key benefit of monorepo: runtime-free type sharing.
// apps/server/src/routes/users.tsimport { z } from "zod"import type { SessionUser } from "@repo/contracts"app.get("/api/users", requireSession(authService), requirePermission("users.read"), async (c) => { const user: SessionUser = c.get("sessionUser") return c.json(await userService.listUsers(user))})
// apps/web/app/routes/users.tsximport type { SessionUser } from "@repo/contracts"function UsersPage() { const [users, setUsers] = createSignal<SessionUser[]>([]) // Same type — no API client generation needed}
# Generate SQL migration from schema changesbun run db:generate# Apply migrations to dev databasebun run db:migrate# Open Drizzle Studio (visual schema browser)bun run db:studio
Run db:generate after every schema change. Drizzle Kit diffs the current schema against the previous migration and generates only the incremental SQL.