Production-ready SvelteKit template with authentication, i18n, database, and modern tooling.
| Layer | Technology |
|---|---|
| Framework | SvelteKit 2 + Svelte 5 (runes) |
| Build | Vite 7 via Vite Plus |
| Language | TypeScript (strict mode) |
| Styling | Tailwind CSS 4 |
| Database | PostgreSQL + Drizzle ORM (strict mode) |
| Auth | BetterAuth (email/password, Google OAuth) |
| i18n | Paraglide JS (en, cs) |
| Testing | Vitest + Playwright + Testing Library |
| Linting | ESLint + Stylelint + OxLint (via Vite Plus) |
| Formatting | OxFormatter (via Vite Plus) |
| Dead code | Knip |
| Component dev | Storybook 10 |
| Deployment | Cloudflare Pages |
# 1. Install dependencies
pnpm install
# 2. Copy environment variables
cp .env.example .env
# Edit .env with your DATABASE_URL and AUTH_SECRET
# 3. Start PostgreSQL (requires Docker)
pnpm run db:start
# 4. Push database schema
pnpm run db:push
# 5. Start dev server
pnpm run dev
| Script | Description |
|---|---|
pnpm run dev |
Start dev server (vp dev) |
pnpm run build |
Production build (vp build) |
pnpm run preview |
Preview via Cloudflare Pages locally |
pnpm run storybook |
Start Storybook on port 6006 |
| Script | Description |
|---|---|
pnpm run lint |
OxLint + ESLint (type-aware) |
pnpm run lint:css |
Stylelint for CSS and Svelte |
pnpm run format |
Format with OxFormatter |
pnpm run check:all |
Full suite: lint + typecheck + eslint + stylelint + knip + svelte-check |
| Script | Description |
|---|---|
pnpm run test |
Unit tests with Vitest (80% coverage threshold) |
pnpm run test:e2e |
E2E tests with Playwright (Chromium) |
| Script | Description |
|---|---|
pnpm run db:start |
Start PostgreSQL via Docker Compose |
pnpm run db:push |
Push schema changes to database |
pnpm run db:generate |
Generate migration files |
pnpm run db:migrate |
Run migrations |
pnpm run db:studio |
Open Drizzle Studio (DB GUI) |
| Script | Description |
|---|---|
pnpm run cf:types |
Generate Cloudflare Workers types |
pnpm run build:storybook |
Build static Storybook |
Copy .env.example to .env and configure:
| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | PostgreSQL connection string |
AUTH_SECRET |
Yes | 32-byte base64 secret (openssl rand -base64 32) |
ORIGIN |
No | App URL (default: http://localhost:5173) |
GOOGLE_CLIENT_ID |
No | Google OAuth client ID |
GOOGLE_CLIENT_SECRET |
No | Google OAuth client secret |
Google OAuth is automatically enabled when both GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET are set.
Full auth system in src/lib/server/auth.ts with:
Auth tables are defined in src/lib/server/db/schema.ts: user, session, account, verification.
src/hooks.server.ts injects event.locals.user and event.locals.session into every request.
Email callbacks in auth.ts currently log to console. Replace the sendResetPassword and sendVerificationEmail callbacks with your email service (Resend, SendGrid, Postmark, etc.).
requireEmailVerification: truesendOnSignUp: trueAUTH_SECRETORIGIN to your production URLURL-based i18n with cookie fallback. English is the base locale (no prefix), Czech uses /cs/ prefix.
Configured in vite.config.ts as ['url', 'cookie', 'baseLocale']:
/cs/about = Czech)<script>
import * as m from '$lib/paraglide/messages';
</script>
<h1>{m.welcome()}</h1>
<p>{m.hello_world({ name: 'World' })}</p>
project.inlang/settings.json locales arraymessages/{locale}.json with translationsvite.config.ts urlPatternsInstall the Inlang VS Code extension for inline translation editing and key extraction.
If your project doesn't need i18n:
@inlang/paraglide-js from package.jsonparaglideVitePlugin(...) from vite.config.tsproject.inlang/, messages/, src/hooks.tsparaglideMiddleware from src/hooks.server.tssrc/lib/paraglide/ from .gitignore%lang% back to en in src/app.htmlinlang.vs-code-extension from .vscode/extensions.jsonPress Alt+X during development to toggle the Svelte Inspector. Click any element to jump to its source code in your editor. Configured in svelte.config.js under vitePlugin.inspector.
Type-safe client-server RPC. Functions defined with the remote function API run on the server but can be called from the client with full type safety. Enabled via kit.experimental.remoteFunctions in svelte.config.js.
Use await directly in Svelte components without {#await} blocks. Enabled via compilerOptions.experimental.async in svelte.config.js.
Component development environment with Tailwind CSS support.
pnpm run storybook # dev server on port 6006
pnpm run build:storybook # static build
Place story files next to components: src/lib/components/Button.stories.svelte or Button.stories.ts.
This template uses @sveltejs/adapter-cloudflare. Deploy via:
npx wrangler pages deploy .svelte-kit/cloudflareConfiguration is in wrangler.jsonc. Add Cloudflare bindings (KV, D1, R2) in src/app.d.ts under App.Platform.
To deploy elsewhere, swap the adapter in svelte.config.js:
# For auto-detection
pnpm add -D @sveltejs/adapter-auto
# Then change import in svelte.config.js:
# import adapter from '@sveltejs/adapter-auto';
# For Node.js / Docker
pnpm add -D @sveltejs/adapter-node
# For Vercel
pnpm add -D @sveltejs/adapter-vercel
# For static sites
pnpm add -D @sveltejs/adapter-static
See SvelteKit adapters docs for the full list.
.github/workflows/ci.yml runs on PRs and pushes to dev/main:
check:all)Connect your repo to Cloudflare Pages for automatic deployments on push to main and PR preview environments.
snake_case or PascalCase (no camelCase)PascalCaseUPPER_CASE, snake_case, or PascalCase$state, $derived, $props). No legacy patterns.inline-type-imports stylesrc/
app.css # Tailwind CSS entry point
app.d.ts # Global type definitions
app.html # HTML shell (with %lang% for i18n)
hooks.ts # Client hooks (i18n URL rerouting)
hooks.server.ts # Server hooks (i18n middleware + auth session)
lib/
auth-client.ts # BetterAuth client (for use in components)
index.ts # $lib public exports
assets/ # Static assets (favicon, etc.)
paraglide/ # Generated i18n runtime (gitignored)
server/
auth.ts # BetterAuth server config
db/
index.ts # Drizzle client instance
schema.ts # Database schema (auth tables)
routes/
+layout.svelte # Root layout (CSS, favicon)
+page.svelte # Home page
messages/ # Translation files (en.json, cs.json)
project.inlang/ # Inlang i18n project config
tests/e2e/ # Playwright E2E tests
.storybook/ # Storybook configuration
.github/workflows/ # CI pipeline
npx [email protected] create --template minimal --types ts --no-install template-sveltekit