Dive into Svelte 5's powerful runes and SvelteKit's full-stack capabilities. This hands-on guide walks you through setup, routing, data handling, and more for building modern web apps.
## Getting Started with Svelte 5 and SvelteKit
Hey there, fellow developer! If you're excited about creating lightning-fast, intuitive web applications, Svelte 5 paired with SvelteKit is your dream combo. Svelte 5 brings revolutionary "runes" for state management, making reactivity feel magical and straightforward. SvelteKit, the official app framework, handles everything from routing to server-side rendering (SSR) seamlessly. Together, they let you build full-stack apps with minimal boilerplate.
This guide is your roadmap. We'll cover installation, project anatomy, key features like routing and forms, and Svelte 5's new runes. By the end, you'll be equipped to launch production-ready apps. Let's jump in!
## Step 1: Setting Up Your Development Environment
First things first: prerequisites. Ensure you have Node.js (version 18 or later) installed. You can grab it from the official Node.js site.
To scaffold a new SvelteKit project, open your terminal and run:
```bash
npm create svelte@latest my-sveltekit-app
cd my-sveltekit-app
npm install
```
During setup, choose options like Skeleton project, TypeScript (recommended for better dev experience), ESLint, Prettier, and Playwright for testing. For Svelte 5 compatibility, select the latest stable versions—the installer handles this automatically.
Kick off the dev server:
```bash
npm run dev
```
Your app lives at `http://localhost:5173`. Edit `src/routes/+page.svelte` to see hot reload in action. Boom— you're coding!
Pro tip: For production builds, use `npm run build` and preview with `npm run preview`. Deploy easily to platforms like Vercel or Netlify.
Check out the [SvelteKit GitHub repository](https://github.com/sveltejs/kit) for the latest updates and issues.
## Step 2: Understanding Project Structure
SvelteKit projects follow a file-based routing system rooted in `src/routes`. Here's the breakdown:
- **`src/routes/`**: Defines your app's pages and layouts.
- `+page.svelte`: A route's UI component.
- `+page.ts`: Load data for that page (more on this later).
- `+layout.svelte` / `+layout.ts`: Shared UI and data across routes.
- `(group)`: Route groups for organizing without URL impact.
- `+error.svelte`: Custom error pages.
- **`src/lib/`**: Reusable components, utilities, and stores.
- **`src/app.html`**: Main HTML template with `%sveltekit.body%` and `%sveltekit.head%` placeholders.
- **`static/`**: Served as-is (images, robots.txt).
- **`app.config.js`**: App-wide settings like title.
Example: `src/routes/blog/[slug]/+page.svelte` creates `/blog/my-post` with `slug` as a dynamic param.
This structure keeps things intuitive—no complex config files!
## Step 3: Mastering Routing
Routing in SvelteKit is a breeze. Pages are Svelte components in `src/routes`:
- Static: `src/routes/about/+page.svelte` → `/about`
- Dynamic: `src/routes/users/[id]/+page.svelte` → `/users/123`, access `id` via `$page.params.id`
- Nested: Folders create hierarchies.
- Layouts: `+layout.svelte` wraps child pages.
Advanced patterns:
- **Optional params**: `[param]?`
- **Catch-all**: `[[...slug]]`
- **API routes**: `+server.js` for endpoints like `src/routes/api/users/+server.js`.
Here's a quick dynamic page example:
```svelte
<!-- src/routes/users/[id]/+page.svelte -->
<script>
export let data;
$: user = data.user;
</script>
<h1>{user.name}</h1>
```
Layouts ensure consistent navbars or themes across sections.
## Step 4: Loading Data Like a Pro
Data loading happens in `+page.ts` or `+layout.ts` using `load` functions. These run on server (SSR) and client (hydration).
```ts
// src/routes/users/[id]/+page.ts
import { error } from '@sveltejs/kit';
export async function load({ params }) {
const user = await fetchUser(params.id);
if (!user) throw error(404, 'User not found');
return { user };
}
```
Data flows to the page via `export let data`. Universal loads work everywhere; use `url` or `fetch` for context-aware fetching.
For streaming or props, explore `formActions` later.
## Step 5: Handling Forms Effortlessly
SvelteKit supercharges forms with progressive enhancement.
```svelte
<!-- +page.svelte -->
<form method="POST" action="?/createUser">
<input name="name" />
<button>Submit</button>
</form>
<script>
$effect(() => {
if ($page.status === 201) {
// Success handling
}
});
</script>
```
In `+page.server.ts`:
```ts
// +page.server.ts
import { superValidate } from 'sveltekit-superforms';
export const actions = {
createUser: async ({ request }) => {
const form = await superValidate(await request.formData());
// Process and redirect
return { form };
}
};
```
This handles validation, errors, and optimistically updates UI. Libraries like `sveltekit-superforms` add schema validation.
## Step 6: Server-Side Rendering (SSR) and Prerendering
SvelteKit defaults to SSR for SEO and perf. Control per-route:
```ts
// +page.ts
export const prerender = true; // Static at build
export const ssr = false; // Client-only
```
SSR loads data server-side; CSR hydrates on client. Hybrid mode rocks for dynamic sites.
## Step 7: Embracing Svelte 5 Runes
Svelte 5's killer feature: runes for explicit reactivity. No more context headaches!
- **`$state`**: Reactive state.
```svelte
<script>
let count = $state(0);
</script>
<button onclick={() => count++}>{count}</button>
```
- **`$derived`**: Computed values.
```svelte
let count = $state(0);
let double = $derived(count * 2);
```
- **`$effect`**: Side effects (replaces `onMount`, etc.).
```svelte
$effect(() => {
const id = setInterval(() => count++, 1000);
return () => clearInterval(id);
});
```
Runes shine in components and snippets. Props become reactive automatically.
Explore the [Svelte GitHub repository](https://github.com/sveltejs/svelte) for rune deep dives.
## Step 8: Stores for Shared State
Svelte stores persist state across components:
```ts
// src/lib/stores.js
import { readable, writable } from 'svelte/store';
export const count = writable(0);
```
Subscribe with `$count`. Perfect for themes or user sessions.
## Step 9: Building Components
Components are portable: `<MyButton />`. Pass props:
```svelte
<!-- MyButton.svelte -->
<script>
export let label = 'Click me';
export let disabled = $state(false);
</script>
<button {disabled}>{label}</button>
```
Events: `on:click={() => handleClick()}`. Slots for flexibility.
## Step 10: Real-World Tips and Best Practices
- **TypeScript**: Integrates flawlessly—use `$page.data` types.
- **Testing**: Vitest for units, Playwright for E2E.
- **Styling**: Scoped CSS, Tailwind, or CSS vars.
- **Deployment**: Adapters for Node, Vercel (`adapter-auto`).
- **Perf**: Use `$inspect` for debugging runes.
Example app: A todo list with server actions, runes for state, and dynamic routing.
```svelte
<!-- TodoApp.svelte -->
<script>
let todos = $state([]);
let newTodo = $state('');
$effect(async () => {
todos = await fetchTodos();
});
</script>
<input bind:value={newTodo} />
<button onclick={addTodo}>Add</button>
<ul>{todos.map(t => <li>{t.text}</li>)}</ul>
```
## Wrapping Up
Svelte 5 and SvelteKit make web dev joyful—compile-time magic, zero-config fullstack, and runes for future-proof code. Experiment, check docs, and contribute! Your next killer app awaits.
<div style="text-align: center; margin-top: 2rem;">
<a href="https://cursor.directory/svelte5-sveltekit-development-guide" target="_blank" rel="noopener noreferrer" class="view-full-resource-btn" style="display: inline-block; background-color: #f97316; color: white; padding: 12px 24px; border-radius: 8px; text-decoration: none; font-weight: 600; transition: background-color 0.2s;">View Full Resource</a>
</div>