Tech Stack
Explore the GenerateSaaS tech stack, from Next.js 16 and Hono RPC to Better Auth, Drizzle ORM with Postgres, Inngest, and Redis, fully typed end to end.
GenerateSaaS pairs a Next.js App Router frontend with a fully typed Hono RPC backend, sharing one set of @repo/* packages. Every layer is picked for type safety, deploy portability, and a boilerplate you fully own.
The stack at a glance
Each layer maps to a workspace package or app dependency, with the version pinned in the repo.
| Layer | Tech | Lives in | Why |
|---|---|---|---|
| Frontend | Next.js 16 App Router + React 19 | apps/web-next | Server Components by default, client only where interactive; prerenders marketing routes |
| Backend | Hono 4 RPC | @repo/api | End-to-end typed client via hc<AppType>(); deploys anywhere, not just Vercel |
| Auth | Better Auth 1.6 | @repo/auth | Sessions, OAuth, 2FA, passkeys, orgs, API keys - no third-party auth vendor |
| Data | Drizzle ORM 0.45 + Postgres | @repo/database | Typed schema and queries; SQL you can read, migrations you control |
| Jobs | Inngest 4 | @repo/runtime | Durable background/scheduled jobs with retries; no separate queue infra |
| UI | shadcn/ui + Tailwind CSS 4 + Phosphor icons | apps/web-next | Accessible primitives you copy into the repo and own; utility-first styling |
| Cache | Redis (ioredis or @upstash/redis) | @repo/runtime | Caching, rate-limit store, and distributed mutex; the environment variables depend on your cache choice |
| Validation | Zod 4 + standard-schema | @repo/api, app forms | Shared schemas validate API input via sValidator and forms via react-hook-form |
| Tooling | pnpm 11 + Turborepo 2 + TypeScript 6 | repo root | Fast workspace installs, cached task graph, strict types everywhere |
There is no @repo/jobs or @repo/cache package - Inngest and Redis both live in @repo/runtime, which the app pulls in transitively through @repo/api.
How the pieces connect
- The Next.js app imports backend logic only through
@repo/*packages - never from a sibling app. - It builds a typed RPC client with
hc<AppType>(), so a backend route change surfaces as a frontend type error. - Server Components read data through the server client; Server Actions and the browser client handle mutations and client reads.
- next-intl drives i18n and next-themes drives dark mode.
Type safety end to end
The same types flow from database to UI with no codegen step.
// Drizzle schema → inferred row types → Hono route → typed RPC client
import { hc } from "hono/client";
import type { AppType } from "@repo/api";
const api = hc<AppType>(process.env.NEXT_PUBLIC_API_URL!);
const res = await api.posts.$get(); // fully typed response, no manual DTOsThe browser client lives in lib/api/client.ts; Server Components and Server Actions use getServerApi() from lib/api/server.ts, which forwards the session cookie.
Frequently asked questions
Do I have to deploy on Vercel?
No. The Hono backend and @repo/* packages use web-standard APIs, so you can host on Vercel, Docker, Fly.io, Railway, or any Node host. See deployment.
Is there a separate API server? By default the Hono API runs inside the Next.js app. You can split it into a standalone backend later - see separate backend.
Is Redis optional?
No. Redis backs caching, the rate limiter, and the distributed mutex in every environment. The self-hosted choice uses ioredis and requires REDIS_URL; the Upstash choice uses @upstash/redis and requires UPSTASH_REDIS_REST_URL + UPSTASH_REDIS_REST_TOKEN - see environment variables.
Where do I configure which features are on?
Feature flags live in @repo/config; the typed client and env vars are wired around them. Start with configuration.