An sophisticated boiler-plate built for simplicity.
Carlo's starter for making a SvelteKit app with batteries included on stuff I like after experimenting for years.
This is handcrafted from my own research. This might not work for you, but it works for me. π€
You can also try my other starters:
- π Solid Launch - If you like Solid, but same robust practices.
 
- π Simple and minimal - SvelteKit is the best JS framework for simplicty and getting the job done. Hands-down.
 - β‘οΈ Super-fast dev server - way faster than NextJS thanks to Vite. You need to feel it to believe it! It can also literally build your app in seconds.
 - βοΈ Selfhost-ready - Crafted with simple hosting in mind that'll still probably scale to millions. Just spin up Docker container on a good'ol VPS without locking into serverless. DHH and Shayan influenced me on this. You can still host it on serverless tho. I think? lol
 - π Batteries-included - took care of the hard stuff for you. A well-thought-out folder structure from years of making projects: a design system, components, utilities, hooks, constants, an adequate backend DDD-inspired sliced architecture that isn't overkill, dockerizing your app, and most importantly---perfectly-crafted those pesky config files.
 -  π Authentication-Ready - One thing devs get stuck on. There's a practical auth implemented from scratch here that doesn't vendor-lock you into any auth provider.
- Password
 - Transactional Emails (Forgot Password, Email Verification)
 - OAuth
 - Magic Link
 - User Management Dashboard
 
 
- Bun - Runtime and package manager. You can always switch to Node and PNPM if you wish.
 - Svelte - Frontend framework that I like. Pretty underrated, but awesome!
 - SvelteKit - Like NextJS, but for Svelte and Vite! Simpler and Faster!
 - tRPC - E2E typesafety without context switching. Just amazing DevX.
 - Tailwind - Styling the web has been pretty pleasant with it. I even use it on React Native for work. It's amazing.
 - Prisma - Great migrations workflow, but I want to maximize perf.
 - Kysely - Great typesafe query builder for SQL, minimally wraps around db connection.
 - SQLite/LibSQL (Turso) - Cheapest database, easy to use.
 - Lucia - Makes self-rolling auth easy.
 - SES or MimePost - Emails
 - Backblaze - Cheap blob object storage with an S3-compatible API.
 - Paddle - Accept payments and pay foreign taxes.
 
I'll assume you don't want to change anything with this setup after cloning so let's get to work!
- 
Copy the environment variables
cp .env.example .env
 - 
Replace the
<absolute_url>in the local database with:pwd # If it outputs: /User/Projects/svelte-launch # Replace the .env with: DATABASE_URL="file:/User/Projects/svelte-launch/local.db"
 - 
Generate
bun db:generate # generates Kysely and Prisma client types. bun db:migrate # migrates your database.
 - 
Install deps and run dev
bun install bun dev
 
I took care of the painstaking parts to help you develop easily on a SPA + SSR + backend paradigm. You can take take these practices to different projects as well.
- 
Make use of the
code-snippetsI added. It'll help! - 
Check all typescript errors (
Cmd+Shift+B>tsc:watch tsconfig.json). - 
Authentication Practices - I have these out-of-the-box for you so you won't have to build it.
- 
Getting Current User.
import { authStore } from '@/stores/auth.store';
 - 
Login, Logout, Register
import { login, logout, register } from '@/stores/auth.store';
 - 
Hydrating Current User
This will also automatically hydrate in your layouts. Anywhere you use
$authStore, it's magic.// page.server.ts export async function load(event: PageServerLoadEvent) { const trpcClient = initTRPCSSRClient(event.request.headers, event.setHeaders); const result = await trpcClient.auth.currentUser.query(); if (!result.user) { throw redirect(302, '/dashboard'); // Must be a public route here. } return { user: result.user ?? null, }; } // page.svelte import { authStore, hydrateAuthStore } from '@/stores/auth.store'; let { data } = $props(); hydrateAuthStore(data.user);
 - 
Protecting Routes (Client-Side) - Just block the content.
<script> import ProtectedRoute from '@/components/common/protected-route.svelte'; </script> <ProtectedRoute> On the server (hydration), this part will not be rendered if unauthenticated. On the client, you will be redirected to a public route if unauthenticated. </ProtectedRoute>
 - 
Protecting Routes (SSR) - Automatically redirect.
import { initTRPCSSRClient } from '@/lib/trpc-ssr-client.js'; import { redirect } from '@sveltejs/kit'; import type { PageServerLoadEvent } from './$types'; export async function load(event: PageServerLoadEvent) { const trpcClient = initTRPCSSRClient(event.request.headers, event.setHeaders); const result = await trpcClient.auth.currentUser.query(); if (!result.user) { throw redirect(302, '/dashboard'); // Must be a public route here. } return { user: result.user ?? null, }; }
 
 - 
 - 
Dataloading Practices - Also have these out-of-the-box for most usecases since they're tricky to do if you're clueless:
- Tanstack Query (Client-only) - Use 
trpc-client.ts - Hydrated Tanstack Query (SSR) - Use 
create-dehydrated-state.ts+trpc-ssr-client.ts 
 - Tanstack Query (Client-only) - Use 
 
My backend architecture is inspired by DDD where I separate in layers, but I keep it pragmatic by not going too overkill with Entities, Domains, and Aggregates. I personally still like the anemic data-driven architecture for most of my apps since the apps I make aren't too business-logic-heavy.
.
βββ server/ # - root
    βββ dao/ # - data-access-objects
    β   βββ *.dao.ts
    βββ modules/
    β   βββ <module>/
    β       βββ services/
    β       β   βββ *.service.ts # 1 service usecase
    β       βββ <module>.controller.ts
    βββ _app.ts # - root TRPC router.dao- abstracted away all queries here to interface with them as plain functions. It actually helps me mentally collocate db queries from service logic when I'm using them inside the service.modules- a vertical slice of each module-group. This just depends on how I feel about grouping them. You get better overtime.<module>.controller.ts- pretty much a group of http endpoints. I can put the DTOs/Validations for each endpoint here without context-switching.services- these are even smaller pieces of logic that can be used inside each endpoint. It's not necessary to use if the app isn't too big, but it helps._app.ts- The root trpc router where theAppRoutertype is exported.
Warning
Still in progress
Here are some guides on how to deploy.
- Kamal (self-host VPS - I recommend)
 - Dokku (self-host VPS)
 - Caprover (self-host VPS)
 - Cloudflare (serverless + static)
 - Vercel (serverless + static)
 - Netlify (static)
 
I'll probably make a swapping guide soon. To replace to these:
- Runtime: Bun -> Node
 - Package Manager: Bun -> PNPM
 - ORM: Prisma -> Drizzle
 - Database: SQLite -> PostgreSQL, CockroachDB, MongoDB