Svelte 5 Core Knowledge
Full Reference: See advanced.md for WebSocket store patterns, room management, Socket.IO integration, and SvelteKit SSE patterns.
Deep Knowledge: Use mcp__documentation__fetch_docs with technology: svelte for comprehensive documentation.
When NOT to Use This Skill
Skip this skill when:
-
Working with Svelte 4 or earlier (use Svelte 4 docs)
-
Building React applications (use frontend-react )
-
Using Vue framework (use vue-composition )
-
Working with Angular (use angular )
-
Need only vanilla JavaScript (no framework needed)
Component Structure
<script lang="ts"> interface Props { name: string; count?: number; }
let { name, count = 0 }: Props = $props();
let localState = $state(''); let doubled = $derived(count * 2);
function handleClick() { localState = 'clicked'; } </script>
<div> <h1>Hello {name}</h1> <p>Count: {count}, Doubled: {doubled}</p> <button onclick={handleClick}>Click</button> </div>
<style> div { padding: 1rem; } </style>
Runes (Svelte 5)
Rune Purpose
$state
Reactive state
$derived
Computed values
$effect
Side effects
$props
Component props
$bindable
Two-way bindable props
Key Concepts
-
No virtual DOM - compiles to vanilla JS
-
Scoped CSS by default
-
{#if} , {#each} , {#await} blocks
-
bind: for two-way binding
-
use: for actions (reusable behaviors)
Migration from Svelte 4
<!-- Svelte 4 --> <script> export let count = 0; $: doubled = count * 2; </script>
<!-- Svelte 5 --> <script> let { count = 0 } = $props(); let doubled = $derived(count * 2); </script>
Anti-Patterns
Anti-Pattern Why It's Bad Correct Approach
Using Svelte 4 $: syntax Deprecated in Svelte 5 Use $derived rune
Not using $props()
Old prop syntax Use let { prop } = $props()
Using {@html} without sanitization XSS vulnerability Use DOMPurify before rendering
Complex logic in templates Hard to read/test Extract to $derived or functions
Not cleaning up in onDestroy
Memory leaks Clear timers, unsubscribe
Overusing stores Unnecessary complexity Use component state when possible
Quick Troubleshooting
Issue Likely Cause Solution
State not reactive Using regular let
Use $state() rune
Derived not updating Not using $derived
Convert to $derived()
Effect running too often Missing dependencies Check $effect dependencies
Props not updating Using old syntax Use $props() rune
Memory leaks No cleanup Add onDestroy() lifecycle
Binding not working Wrong syntax Use bind:value not :value
Production Readiness
Security
<script lang="ts"> import DOMPurify from 'dompurify'; let { rawHtml }: { rawHtml: string } = $props(); let safeHtml = $derived(DOMPurify.sanitize(rawHtml)); </script>
{@html safeHtml}
Testing
import { render, screen } from '@testing-library/svelte'; import userEvent from '@testing-library/user-event'; import Counter from './Counter.svelte';
describe('Counter', () => { it('increments count on click', async () => { const user = userEvent.setup(); render(Counter, { props: { initial: 0 } });
const button = screen.getByRole('button');
await user.click(button);
expect(screen.getByText('Count: 1')).toBeInTheDocument();
}); });
Monitoring Metrics
Metric Target
Bundle size < 50KB
First Contentful Paint < 1s
Time to Interactive < 2s
Hydration time < 100ms
Checklist
-
Svelte 5 runes ($state, $derived, $effect)
-
No {@html} with user input
-
Error boundaries in SvelteKit
-
Virtual lists for large data
-
Lazy loaded components
-
Proper ARIA attributes
-
Testing with @testing-library/svelte
-
Server-side rendering enabled
-
Prerendering static pages
-
Bundle analysis
Reference Documentation
-
Runes Cheatsheet
-
Component Patterns