Modern, type-safe/RPC starter monorepo with foundations for building scalable SaaS products with clean architecture, automation, and great developer experience.
- 📚 Documentation: zerostarter.dev/docs
- 🤖 AI / LLMs: zerostarter.dev/llms.txt
- 🐦 X: @nrjdalal
- 💬 Discord: Join the community
ZeroStarter is stable and production-ready. We're actively adding new features and integrations day-by-day.
Note
For a deeper dive, see the Architecture documentation.
Every item below is wired and working out of the box, not just a dependency in package.json.
- Runtime & Build: Bun (runtime and package manager) with Turborepo for caching and task orchestration
- Language: TypeScript in strict mode, end-to-end from the database to the UI
- Frontend: Next.js 16 (App Router, Turbopack) with React 19 and the React Compiler
- Styling & UI: Tailwind CSS v4 and shadcn/ui on Base UI primitives
- Backend: Hono with OpenAPI and an interactive Scalar reference at
/api/docs - Type-Safe RPC: Hono Client for end-to-end types from the backend to the frontend
- Database: PostgreSQL with Drizzle ORM and migrations
- Authentication: Better Auth with GitHub and Google OAuth, organizations, and teams
- Authorization: a role-gated admin console at
/console, backed by the Better Auth admin plugin - Public Waitlist: a waitlist landing + signup API (
/api/waitlist) with an approximate count; the default home for a fresh fork - Rate Limiting: hono-rate-limiter keyed per user, API key, or IP (with Arcjet IP detection)
- Data & Forms: TanStack Query for server state and TanStack Form for forms
- Validation: Zod, shared across the API, forms, and type-safe environment variables
- Analytics: PostHog for product analytics, feature flags, and session replay
- Documentation: Fumadocs with full-text search and auto-generated llms.txt
- Dynamic OG Images: takumi for home, docs, and blog social cards
- SEO: sitemap, robots, and per-page metadata, indexable by default
- Tooling: tsdown (backend bundling), Oxlint and Oxfmt, with Lefthook git hooks and Commitlint
- Automated Releases: changelog generation and a canary-to-main release flow
.
├── api/
│ └── hono/ # Backend API (Hono): /api/agents, /api/auth, /api/docs, /api/v1, /api/waitlist
├── web/
│ └── next/ # Frontend (Next.js App Router): dashboard, admin console, docs, blog
└── packages/
├── auth/ # Better Auth instance (OAuth, organizations, teams, admin)
├── db/ # Drizzle ORM schema and PostgreSQL client
├── env/ # Type-safe environment variables (t3-oss/env + Zod)
└── config/ # Shared config: TS/tsdown bases and the `site` brand identity
Two deployable apps (api/hono and web/next) and four shared packages. Brand identity lives in one place, @packages/config/site, so a fork rebrands by editing a single file.
Note
For details and examples, see the Type-Safe API documentation.
ZeroStarter uses Hono RPC for end-to-end type safety between the backend and frontend.
- Backend: routes in
api/hono/src/routersare exported asAppTypefrom@api/hono. - Frontend: the client at
web/next/src/lib/api/client.tsinfers request and response types fromAppType. - API Docs: an interactive reference is served at
/api/docs(OpenAPI spec at/api/openapi.json).
import { apiClient, unwrap } from "@/lib/api/client"
// Fully typed { data, error } result (never throws)
const { data, error } = await unwrap(apiClient.health.$get())- End-to-end type safety: one type flows from the database through the API to the frontend, so breaking changes fail at compile time, not in production.
- Modular by design: shared packages for auth, database, env, and config that you can swap or extend without fighting the system.
- Production-ready: Docker and Vercel configs, migrations on deploy, rate limiting, and SEO are set up from the first commit.
- Forkable: brand identity is centralized in
@packages/config/site, so making it your own is a one-file change.
# In a new, empty directory (its name becomes your project name):
# scaffold a fresh product: fetches, rebrands, installs, provisions a local
# Postgres (Docker), migrates, and writes .env with a generated auth secret
bunx zerostarter init
# Start the dev servers (web on :3000, api on :4000)
bun run devThat is the whole setup. When Docker is running, init provisions a local Postgres and migrates for you; otherwise set POSTGRES_URL in .env (a hosted database like Neon works) and run bun run db:migrate. GitHub/Google OAuth, PostHog analytics, and user feedback are all optional; add them to .env anytime.
| Command | Description |
|---|---|
bun dev |
Start the api and web dev servers |
bun run build |
Build every workspace |
bun run check-types |
Type-check every workspace |
bun run lint / bun run format |
Lint with Oxlint / format with Oxfmt |
bun run db:generate |
Generate Drizzle migrations from the schema |
bun run db:migrate |
Apply pending migrations |
bun run db:studio |
Open Drizzle Studio |
bun run console:roles |
Grant, revoke, or list admin console access |
bun run shadcn:update |
Update shadcn/ui components |
- Getting Started: introduction, architecture, and project structure
- Authentication & Organizations: OAuth, orgs, teams, and roles
- Type-Safe API: the Hono RPC client
- Database: schema and migrations
- Environment Variables: configuration
- Deployment: Vercel and Docker
- AI / LLMs: optimized documentation
ZeroStarter ships as two deployable apps that share one PostgreSQL database.
- Vercel: deploy
web/nextandapi/honoas separate projects. The API runs pending migrations on deploy. - Docker:
docker compose upbuilds and runs both apps from the included multi-stage Dockerfiles.
Contributions are welcome. Please read the contributing guide first.
MIT License. See LICENSE.md for details.
⭐ Star this repo if it helps, and follow @nrjdalal for updates.
