| name | svelte |
| description | SvelteKit development patterns — runes, component architecture, server-side rendering, form actions, and reactive state |
| layer | domain |
| category | frontend |
| triggers | ["svelte","sveltekit","svelte component","svelte rune","$state","$derived","$effect","+page.svelte","+server.ts","svelte action"] |
| inputs | ["SvelteKit page or component requirements","Svelte reactivity patterns","SvelteKit routing and data loading","Form handling in SvelteKit"] |
| outputs | ["SvelteKit pages, layouts, and endpoints","Svelte 5 rune-based components","Server-side data loading patterns","Form action implementations"] |
| linksTo | ["typescript-frontend","css-architecture","animation","forms"] |
| linkedFrom | ["code-writer","architect"] |
| preferredNextSkills | ["typescript-frontend","css-architecture","forms"] |
| fallbackSkills | ["react","vue"] |
| riskLevel | low |
| memoryReadPolicy | selective |
| memoryWritePolicy | none |
| sideEffects | [] |
SvelteKit Development Patterns
Purpose
Provide expert guidance on SvelteKit application development using Svelte 5 runes, component architecture, server-side rendering, data loading, form actions, and deployment patterns. Focus on idiomatic Svelte patterns that leverage the compiler for optimal performance.
Key Patterns
Svelte 5 Runes
Svelte 5 replaces the implicit reactivity system with explicit runes:
$state — Reactive state declaration:
<script lang="ts">
let count = $state(0);
let items = $state<string[]>([]);
let user = $state<{ name: string; email: string }>({
name: '',
email: '',
});
function increment() {
count++; // Direct mutation is reactive
}
function addItem(item: string) {
items.push(item); // Array mutations are reactive with $state
}
function updateName(name: string) {
user.name = name; // Deep property mutations are reactive
}
</script>
<button
onclick={increment}
class="px-6 py-4 text-base rounded-lg bg-blue-600 text-white transition-all duration-200 hover:bg-blue-700 focus-visible:ring-2 focus-visible:ring-offset-2"
>
Count: {count}
</button>
$derived — Computed values:
<script lang="ts">
let items = $state<{ name: string; done: boolean }[]>([]);
// Simple derivation
let total = $derived(items.length);
let completed = $derived(items.filter(i => i.done).length);
let remaining = $derived(total - completed);
// Complex derivation with $derived.by
let stats = $derived.by(() => {
const done = items.filter(i => i.done);
const pending = items.filter(i => !i.done);
return {
done: done.length,
pending: pending.length,
percentComplete: items.length ? Math.round((done.length / items.length) * 100) : 0,
};
});
</script>
<p class="text-base">{remaining} items remaining ({stats.percentComplete}% complete)</p>
$effect — Side effects:
<script lang="ts">
let searchQuery = $state('');
let results = $state<SearchResult[]>([]);
// Runs when searchQuery changes (auto-tracked)
$effect(() => {
if (searchQuery.length < 2) {
results = [];
return;
}
const controller = new AbortController();
fetch(`/api/search?q=${encodeURIComponent(searchQuery)}`, {
signal: controller.signal,
})
.then(r => r.json())
.then(data => { results = data; })
.catch(() => {});
// Cleanup function
return () => controller.abort();
});
// Pre-effect for DOM measurements
$effect.pre(() => {
// Runs before DOM update
});
</script>
$props — Component props: