Full-stack TypeScript starter β TanStack Start + Hono + oRPC + Drizzle + PostgreSQL.
Scaffolds in one of two shapes: full-stack (apps/api + apps/web) or web-only (apps/web alone, with backend logic in TanStack Start server functions).
| Layer | Technologies |
|---|---|
| Web | Vite + TanStack Start (SPA mode), TanStack Router (file-based), TanStack Query, react-hook-form, zod, shadcn/ui, Tailwind v4 |
| API | Hono, oRPC (RPCHandler + OpenAPIHandler), zod validation, filesystem-routed resources auto-generated by codegen-router |
| Database | Drizzle ORM + PostgreSQL. @ship/db DbService<T> wrappers with typed transaction() and mutation event hooks. Flat methods (findFirst/find/findPage/β¦) surface with/columns relation loading via Drizzle's relational query builder (no .query namespace on the service) and carry a relations generic. |
| Auth | better-auth β email/password + verification + reset + Google OAuth |
| Shared | app-constants workspace package, typed API client via import type { AppClient } from 'api' |
| Infra | Docker, Turborepo, Redis, Socket.IO |
| Deployment | Digital Ocean Apps, Kubernetes (DO / AWS EKS) |
- Node β₯22.13.0 (see
.nvmrc) - pnpm β₯9.5.0 (
corepack enable) - Docker for Postgres + Redis
nvm use && corepack enablepnpm install
pnpm start # spins up infra (postgres + redis), runs codegen + migrations, then api + webWeb: http://localhost:3002 Β· API: http://localhost:3001 Β· API docs: http://localhost:3001/docs Β· Email preview: http://localhost:4000 Β· DB studio: https://local.drizzle.studio
| Command | What it does |
|---|---|
pnpm start |
Boots infra + everything in dev (alias for infra:postgres + turbo-start). |
pnpm infra:postgres |
Redis + Postgres only. |
pnpm turbo-start |
Turborepo dev (assumes infra is running). |
pnpm --filter api dev |
API only on :3001. |
pnpm --filter web dev |
Web only on :3002. |
pnpm --filter api codegen |
Regenerate src/router.ts, src/contract.ts, src/db.ts. |
pnpm --filter api generate |
New Drizzle migration from schema diff. |
pnpm --filter api migrate |
Apply pending migrations. |
pnpm --filter api seed:dev |
Seed dev data (if present). |
pnpm --filter api tsc --noEmit / pnpm --filter web tsc --noEmit |
Typecheck. |
pnpm admin:set <email> |
Promote a user to admin. |
pnpm dashboard |
Drizzle Studio β DB schema/relations viewer + query runner on :4983 (also auto-launched by pnpm start). |
Extend the template with pre-built features. Plugins live in <repo-root>/plugins/ and merge into the template via pnpm plugin:dev.
# Run in dev mode (watches plugin files, re-merges into plugin-dev-server/)
cd template
pnpm plugin:dev ../plugins/auth-starter ../plugins/admin
# Permanently copy plugin files into the template (like shadcn add)
pnpm plugin:install <git-url>
pnpm plugin:uninstall <name>
pnpm plugin:listAvailable plugins: auth-starter, admin, notes, ai-chat, mailer, cloud-storage. See the top-level PLUGINS.md for the catalog and the layout convention.
template/
βββ apps/
β βββ api/ # Hono + oRPC backend (port 3001)
β β βββ src/resources/<name>/{*.schema.ts, endpoints/, methods/, handlers/}
β β βββ src/{db,router,contract}.ts # auto-generated by scripts/codegen-*.ts
β β βββ src/{auth,server,endpoint,event-bus}.ts
β β βββ src/middlewares/ # global/ + gates (is-authorized, is-admin, can-access, can-edit)
β β βββ drizzle/ # migration files
β βββ web/ # Vite + TanStack Start SPA (port 3002)
β βββ src/routes/ # TanStack Router file routes
β βββ src/components/{ui,Table,app-drawer,pill-tab-bar}.tsx
β βββ src/layouts/main-layout/{*, content-layout}.tsx
β βββ src/hooks/use-api.hook.ts # useApiQuery / useApiMutation / useApiForm
β βββ src/services/api-client.service.ts
βββ packages/
β βββ db/ # @ship/db (DbService<T> wrapper + MutationEvent types)
β βββ emails/ # @ship/emails (Resend + React Email templates)
β βββ cloud-storage/ # @ship/cloud-storage (S3-compatible)
β βββ app-constants/ # shared enums / constants
β βββ {eslint,prettier,tsconfig}-config/
βββ plugin-dev-server/ # gitignored merge target for pnpm plugin:dev
βββ scripts/plugin.ts # plugin CLI
βββ docker-compose*.yml # postgres, cloud-storage flavors
Inside template/, see agent_docs/ for the canonical workflows:
api_resource_and_endpoint_workflow.mdβ resource layout, theendpointbase builder + middlewares (isAuthorized/isAdmingates,canAccess/canEdit), transactions, event hooks.web_pages_and_data_access.mdβ file routes, oRPC client, hooks, ported widgets.workflows_dev_build_test.mdβ when to run what.common_failure_modes.mdβ debugging.