SvelteKit didn’t win the framework wars; it doesn’t need to. By 2026 it’s a mature, beloved alternative for teams that prefer simpler abstractions. This post is the working set.
Svelte 5 runes
<script>
let count = $state(0);
let doubled = $derived(count * 2);
$effect(() => {
console.log("count is", count);
});
</script>
<button onclick={() => count++}>{count} → {doubled}</button>
Explicit reactivity primitives: $state, $derived, $effect. Better than the old $: magic. Cleaner TS.
Routes
src/routes/
├── +layout.svelte
├── +page.svelte → /
├── about/
│ └── +page.svelte → /about
├── posts/
│ ├── +page.svelte → /posts
│ └── [slug]/
│ ├── +page.svelte → /posts/<slug>
│ └── +page.server.ts
File-system routing. +page.svelte, +page.server.ts (server-side load), +page.ts (universal load).
Load functions
// +page.server.ts
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ params, locals }) => {
const post = await db.post.findUnique({ where: { slug: params.slug } });
if (!post) throw error(404);
return { post };
};
<!-- +page.svelte -->
<script lang="ts">
let { data } = $props();
</script>
<h1>{data.post.title}</h1>
Server runs load; data passed as props to the page. Type-safe end-to-end.
Form actions
// +page.server.ts
export const actions = {
create: async ({ request, locals }) => {
const form = await request.formData();
const title = form.get('title');
await db.post.create({ data: { title } });
return { success: true };
},
};
<form method="POST" action="?/create">
<input name="title" />
<button>Create</button>
</form>
Forms work without JS; enhance with use:enhance for SPA-like UX. Similar to Remix’s pattern.
Hooks
// hooks.server.ts
export const handle: Handle = async ({ event, resolve }) => {
event.locals.user = await getUserFromCookie(event);
return resolve(event);
};
Auth, logging, headers — middleware-style. Available throughout server-side via locals.
Adapters
// svelte.config.js
import adapter from '@sveltejs/adapter-node'; // Node server
// or '@sveltejs/adapter-cloudflare' // CF Workers
// or '@sveltejs/adapter-vercel'
// or '@sveltejs/adapter-static' // SSG
export default { kit: { adapter: adapter() } };
Same code; different deploy targets. Excellent flexibility — Vercel, Cloudflare Workers, Node, static export, AWS Lambda.
Performance
- Bundle size: typically 30-40% smaller than React equivalents.
- Runtime: Svelte’s compiled output is lean.
- HMR: very fast.
- First paint: small JS payload helps.
For latency-sensitive / mobile-heavy apps: SvelteKit’s bundle savings are real.
TypeScript
<script lang="ts">
import type { User } from '$lib/types';
let { user, onUpdate }: { user: User; onUpdate: (u: User) => void } = $props();
</script>
Solid TS support. Generated $types per route. Less magic than Next.js.
Stores (legacy)
Pre-runes Svelte had stores. Still supported; less needed in Svelte 5:
import { writable } from 'svelte/store';
export const count = writable(0);
Most state in Svelte 5: just runes in shared modules.
Comparison to Next.js
| SvelteKit | Next.js | |
|---|---|---|
| Component model | Svelte | React |
| Server / client | +page.server.ts / +page.ts | RSC / Client Components |
| Mutations | Form actions | Server Actions |
| File routing | Folders | Folders |
| Bundle size | Smaller | Larger |
| Ecosystem | Smaller | Bigger |
| Hosting | Many adapters | Vercel-best |
| Learning curve | Lower | Higher (RSC) |
| Hiring | Harder | Easier |
For pure DX: SvelteKit. For ecosystem / hiring: Next.js.
Real-world patterns
Auth
// hooks.server.ts
export const handle: Handle = async ({ event, resolve }) => {
const session = event.cookies.get('session');
if (session) {
event.locals.user = await verifySession(session);
}
return resolve(event);
};
// +page.server.ts (protected)
export const load: PageServerLoad = async ({ locals }) => {
if (!locals.user) throw redirect(302, '/login');
return {};
};
Data fetching
// Universal load (runs server + client)
// +page.ts
export const load: PageLoad = async ({ fetch }) => {
const res = await fetch('/api/posts');
return { posts: await res.json() };
};
// Server-only load
// +page.server.ts
export const load: PageServerLoad = async () => {
return { posts: await db.post.findMany() };
};
+page.ts runs both sides; safe data only. +page.server.ts runs server-only; can use secrets, DB.
API routes
// +server.ts
import type { RequestHandler } from './$types';
export const GET: RequestHandler = async ({ params }) => {
const post = await db.post.findUnique({ where: { id: params.id } });
return new Response(JSON.stringify(post));
};
Tied to file-system routes. REST endpoints next to pages.
Deployment patterns
- Vercel: 1-click; great DX.
- Cloudflare Workers + KV: edge; cheap; AWS-free.
- Self-host Node: standard server.
- Static (adapter-static): SSG for blog/docs.
When to pick SvelteKit
- Small/medium team without React experience.
- Performance-critical (bundle size, perceived speed).
- Wanting less framework magic.
- DX-driven decisions.
When to pick Next.js
- Big team with React experience.
- Need component library ecosystem.
- Hiring market matters.
- Vercel-first deployment.
Both are valid in 2026.
Common mistakes
1. Stores when runes work
Old habits. Rewrite to runes for Svelte 5.
2. Universal +page.ts for sensitive data
Runs on client too; secrets leak. Use +page.server.ts.
3. Adapter mismatch
adapter-node deployed on Cloudflare Workers fails. Match adapter to target.
4. Form action without progressive enhancement
use:enhance is the difference between full reload and SPA UX.
5. Missing $types
Skipping types; lose end-to-end safety. Run svelte-kit sync to generate them.
What I’d ship today
For a new SvelteKit app:
- Svelte 5 runes universally.
+page.server.tsfor protected pages.- Form actions with
use:enhancefor UX. - adapter-node or adapter-cloudflare based on hosting.
- Drizzle / Prisma for DB.
- Zod for validation.
- Vitest for tests.
Read this next
- Next.js App Router 2026
- TypeScript Monorepo 2026
- Server Actions vs Traditional APIs 2026
- Edge Compute 2026
If you want my SvelteKit + Drizzle + Lucia auth starter, it’s at rajpoot.dev .
Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .