An opinionated SvelteKit stack — auth, database, linting, git hooks, and local-prod DB parity already set up. Product scope for each project lives in docs/product.md.
- Framework: SvelteKit 2 + Svelte 5
- Language: TypeScript
- Styling: Tailwind CSS 4 + Bits UI (headless)
- Database: PostgreSQL 17 (Docker locally, Neon in production)
- ORM: Drizzle
- Auth: Better Auth (Google OAuth only)
- Deploy: Vercel (
mainbranch only) - Testing: Vitest (unit + browser component tests)
- Package manager: Bun
git clone git@github.com:mislam/sveltekit-stack.git my-app
cd my-app && rm -rf .gitSet the project name (e.g. my-app) in package.json, compose.yaml, and bun.lock.
git init
git add -A && git commit -m "chore: scaffold from sveltekit-stack"bun install
cp .env.example .env
bun auth:secret --writeAdd GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET to .env, and configure a local redirect URI — see Better Auth docs.
bun dev:up
bun db:push
bun devDev server: http://localhost:5173
Update docs/product.md with your product scope.
bun dev:up # start Postgres + Neon proxy (Docker)
bun dev # SvelteKit dev server
bun dev:down # stop Docker servicesbun check # typecheck (svelte-check)
bun format # Prettier write
bun lint # ESLint + Prettier check
bun lint:fix # ESLint fix + Prettier writebun run test # run all tests once (CI-style)
bun run test:unit # Vitest watch modeDo not use bun test — that invokes Bun's built-in runner, not this project's Vitest setup.
Same driver stack as production (@neondatabase/serverless + drizzle-orm/neon-http), with Postgres and a Neon HTTP proxy in Docker (docker/neon-proxy/).
flowchart LR
App["App<br/>(neon-http)"] -->|HTTP :4444| Proxy["Neon proxy"]
Proxy --> DB[(Postgres :5432)]
Kit["Drizzle Kit"] -->|TCP| DB
Offline: add 127.0.0.1 db.localtest.me to /etc/hosts.
bun dev:up # Postgres + Neon proxy (builds proxy image on first run)
bun db:push # apply schema (requires dev:up)
bun db:generate # generate migrations
bun db:migrate # run migrations
bun db:studio # Drizzle StudioHusky + lint-staged:
- Pre-commit: lint-staged → typecheck → tests
- Commit-msg: Conventional Commits via commitlint