# SaaS Dashboard Kit

> Vite + Hono full-stack SaaS template. $99.

The OTF **SaaS Dashboard Kit** is a complete, deployable SaaS starter. Vite + React 19 + Hono
backend + Postgres + Better Auth + Stripe. Live at [saas.otf-kit.dev](https://saas.otf-kit.dev).

## Stack

| Layer       | Choice                                                         |
| ----------- | -------------------------------------------------------------- |
| Framework   | Vite 6 + React 19 (SPA)                                        |
| Routing     | TanStack Router (hand-wired in `src/main.tsx`)                  |
| Data        | TanStack Query (`staleTime: 10s`, optimistic updates)           |
| Server      | Hono 4 + Bun 1.3 (same process serves API + static SPA)        |
| DB          | Postgres + Drizzle ORM 1.0-beta                                  |
| Auth        | Better Auth 1.3 — email + Google OAuth + demo login             |
| UI          | `@otfdashkit/ui` (Radix + Tailwind, token-driven theming)        |
| Payments    | Stripe Checkout + webhook + Resend license email                 |
| Deploy      | Railway via `scripts/deploy-railway.sh`                          |

## Pre-built screens

The kit ships with **9 screens** that mirror what every B2B SaaS needs:

| Screen                | Path                          | What's there                                                         |
| --------------------- | ----------------------------- | -------------------------------------------------------------------- |
| Landing               | `/`                           | Public marketing landing                                              |
| Login / Signup        | `/auth/login`, `/auth/signup` | 2-col hero + email/password + Google + demo login                    |
| Dashboard             | `/home/dashboard`             | KPIs + AreaChart + BarChart + Timeline                                |
| Tasks                 | `/home/tasks`                 | All issues — RecordTable + IssueDetail Sheet                          |
| Issues board          | `/home/issues-board`          | Kanban (5 status columns)                                             |
| Issues backlog        | `/home/issues-backlog`        | Drag-orderable backlog grouped by priority                            |
| Inbox                 | `/home/inbox`                 | SplitPage notifications inbox                                         |
| Analytics             | `/home/analytics`             | BarChart / LineChart / BarList / ActivityHeatmap                     |
| Projects              | `/home/projects`              | Projects list + create/delete                                         |
| Project detail        | `/home/projects/:id`          | Single project with team + tasks                                      |
| Teams                 | `/home/teams`                 | Members table + GridList + Sheet                                      |
| Settings              | `/home/settings`              | Profile / Workspace / Notifications / Appearance                       |

## Database

- **5 Better-Auth tables**: `user`, `account`, `session`, `jwks`, `verification`
- **12 app tables**: `userPublic`, `workspace`, `team`, `teamMember`, `project`, `issue`,
  `label`, `issueLabel`, `comment`, `attachment`, `notification`, `savedView`

`bun run db:generate` produces clean SQL. `bun run db:migrate` applies it. `bun run db:seed`
loads a deterministic 4-user / 5-project / 50-issue seed.

## Conventions

The kit follows the patterns documented in `CLAUDE.md`:

- **Hooks**: every entity gets a TanStack Query hook with optimistic updates. Copy
  `src/hooks/useProjects.ts`.
- **Routes**: every entity gets a Hono router under `server/routes/`. Copy `server/routes/projects.ts`.
- **Screens**: wrap content in `<FadeIn>` then `<Page>` / `<PageHeader>` / `<PageBody>`.
  Add the route in `src/main.tsx`. Add a sidebar item in `src/components/Sidebar.tsx`.
- **Theming**: `@otfdashkit/tokens` CSS imported first, `@otfdashkit/ui/styles` second.
  Pre-paint default in `index.html` to avoid FOUC.
- **Charts**: `hsl(var(--chart-1))` etc. Deep-clone data with `data.map(d => ({...d}))`.

## Adding things

The kit's [`ai/prompts/`](https://github.com/otf-kit/saas-dashboard/tree/main/ai/prompts) folder has
20+ tested prompts for common tasks: add a CRUD entity, add a chart, add a screen, swap auth
provider, swap payment provider, etc. Each prompt is a copy-paste-into-Claude/Cursor template.

## Deploy

```bash
bash scripts/deploy-railway.sh
```

The script auto-sources `RAILWAY_API_TOKEN` from repo-root `.env`, builds the workspace deps,
swaps `workspace:*` → `latest` from npm, and runs `railway up`. Restoring `package.json` is
handled by a `trap` on script exit.

## Required env

| Variable                                  | Purpose                                          |
| ----------------------------------------- | ------------------------------------------------ |
| `DATABASE_URL`                            | Postgres connection string                        |
| `BETTER_AUTH_SECRET`                      | 32+ chars — signs sessions/JWTs                   |
| `BETTER_AUTH_URL`                         | Public origin (e.g. `https://your-app.com`)       |
| `STRIPE_SECRET_KEY`                        | Stripe live/test secret                          |
| `STRIPE_WEBHOOK_SECRET`                    | Stripe webhook signing secret                    |
| `RAILWAY_API_TOKEN`                        | Read by deploy script                            |

Optional: `GOOGLE_CLIENT_ID` + `GOOGLE_CLIENT_SECRET` for Google sign-in. `DEMO_LOGIN_DISABLED=1`
hides the demo button. `RAILWAY_STATIC_URL` adds Railway's URL to the CORS allowlist.

## Buy

[$99 on otf-kit.dev](https://otf-kit.dev/templates/saas-dashboard) — or get the
[Starter Bundle](/docs/templates/starter-bundle) ($149 = all 4 full-stack kits + 15 landing templates + future kits).
