A production-oriented SvelteKit starter for building subscription products. It ships with authentication, database tooling, a modern UI stack, and patterns for billing and feature gating so you can focus on your product instead of boilerplate.
| Area | Stack |
|---|---|
| Framework | Svelte 5 (runes) + SvelteKit 2 + Vite |
| Auth | Better Auth — sign-up, login, sessions |
| Database | PostgreSQL + Drizzle ORM |
| UI | shadcn-svelte + Tailwind CSS v4 + Lucide icons |
| Billing | Stripe-ready patterns (wire up when you need payments) |
| Features | Plan / feature-flag patterns for tiered access |
| Content | mdsvex for Markdown in Svelte |
| Quality | TypeScript, ESLint, Prettier, Playwright |
Some integrations (billing webhooks, email, full dashboard) are intentionally left for you to configure — the foundation is in place.
Clone and install
bun install
Environment
Copy .env.example to .env and fill in:
| Variable | Description |
|---|---|
DATABASE_URL |
PostgreSQL connection string |
ORIGIN |
Public app URL (e.g. http://localhost:5173 in dev) |
BETTER_AUTH_SECRET |
Random secret (32+ chars in production) — Better Auth docs |
Database
Push the schema to your database:
bun run db:push
Or generate and run migrations:
bun run db:generate
bun run db:migrate
Develop
bun run dev
Open http://localhost:5173. Auth pages live at /login and /signup.
| Command | Description |
|---|---|
bun run dev |
Start dev server |
bun run build |
Production build |
bun run preview |
Preview production build |
bun run check |
Type-check with svelte-check |
bun run lint |
ESLint + Prettier check |
bun run format |
Format with Prettier |
bun run test:e2e |
Playwright end-to-end tests |
bun run db:push |
Push Drizzle schema to DB |
bun run db:generate |
Generate SQL migrations |
bun run db:migrate |
Run migrations |
bun run db:studio |
Open Drizzle Studio |
bun run auth:schema |
Regenerate Better Auth Drizzle schema |
src/
├── routes/ # Pages (file-based routing)
│ ├── login/
│ ├── signup/
│ └── layout.css # Tailwind + theme tokens
├── lib/
│ ├── components/
│ │ ├── ui/ # shadcn-svelte primitives (prefer not to edit)
│ │ └── navigation/ # App chrome (nav, footer)
│ ├── content/ # Shared content / copy
│ └── server/
│ ├── auth.ts # Better Auth config
│ └── db/ # Drizzle client + schema
└── hooks.server.ts # Session + auth handler
src/lib/components/ using ui primitives.src/lib/server/ or +page.server.ts / +server.ts.This template uses shadcn-svelte with the vega style and zinc base color. Styling is Tailwind-first; theme variables are in src/routes/layout.css.
Add a component:
bunx shadcn-svelte@latest add card
Import in Svelte:
import { Button } from "$lib/components/ui/button/index.js";
Use cn() from $lib/utils to merge Tailwind classes. Prefer semantic tokens (bg-background, text-muted-foreground) over hard-coded colors.
See components.json for aliases and registry settings. The src/lib/components/ui/ folder is managed by the CLI — customize via props and class when possible rather than editing primitives.
Better Auth is configured in src/lib/server/auth.ts with the Drizzle adapter. Sessions are available on the server as event.locals.session and event.locals.user (see src/hooks.server.ts).
After changing auth plugins or providers:
bun run auth:schema
bun run db:push # or migrate
DATABASE_URL, ORIGIN, BETTER_AUTH_SECRET).bun run buildadapter-auto. Switch to @sveltejs/adapter-node, adapter-vercel, etc. when you know your host.Scaffolded with sv:
bun x [email protected] create --template minimal --types ts \
--add prettier eslint playwright \
tailwindcss="plugins:typography,forms" \
sveltekit-adapter="adapter:auto" \
drizzle="database:postgresql+postgresql:postgres.js+docker:no" \
better-auth="demo:password" mdsvex \
mcp="ide:claude-code,cursor,other+setup:remote" \
--install bun ./
See AGENTS.md for conventions, dependency notes, and agent-oriented workflows.