Jede Svelte 5 Rune mit dem Svelte-4-Code, den sie ersetzt: $state, $derived, $effect, $props und $bindable, dazu die neue Event- und Snippet-Syntax. Beispiele zum Kopieren.
Runes sind die Compiler-Schlüsselwörter, die Svelte 5 für Reaktivität verwendet. $state deklariert eine reaktive Variable, $derived berechnet einen Wert aus anderem State, $effect führt Code aus, nachdem die Seite aktualisiert wurde, $props liest Komponenten-Props und $bindable markiert eine Prop, an die sich eine Elternkomponente binden darf. Sie ersetzen das reaktive let, das $:-Label und export let aus Svelte 4.
Svelte-4-Syntax und die Rune, die sie ersetzt
Aufgabe
Svelte 4
Svelte 5
Reaktive Variable
let count = 0
let count = $state(0)
Berechneter Wert
$: doubled = count * 2
let doubled = $derived(count * 2)
Seiteneffekt
$: console.log(count)
$effect(() => console.log(count))
Props
export let name
let { name } = $props()
Bindbare Prop
export let value
let { value = $bindable() } = $props()
Event-Handler
on:click={fn}
onclick={fn}
Komponenten-Events
createEventDispatcher
Callback-Props
Slots
<slot />
{#snippet} und {@render}
Wähle eine Rune, um eine Svelte-4-Komponente und ihre Umsetzung in Svelte 5 zu sehen. Beide Varianten eines Paars verhalten sich gleich, sodass du Datei für Datei migrieren und das Ergebnis unterwegs prüfen kannst.
Wähle über die Buttons eine Rune oder eine Syntaxänderung aus.
Vergleiche den Svelte-4-Code links mit dem Svelte-5-Code rechts.
Lies den Hinweis zu der Regel, über die viele stolpern.
Kopiere die Svelte-5-Version in deine Komponente.
Nutze $derived für alles, was sich berechnen lässt. Heb dir $effect für die Kommunikation mit Dingen außerhalb von Svelte auf, etwa dem Dokumenttitel, einem Canvas oder einem Widget eines Drittanbieters.
Denk daran, dass $effect beim Server-Rendering nie läuft, es ist also ein sicherer Ort für Code, der auf window oder document zugreift.
Greif bei großen Arrays, die du immer nur komplett ersetzt, zu $state.raw. Es verzichtet auf den tiefen Proxy und kann nur neu zugewiesen werden.
Übergib $state.snapshot(value) an Bibliotheken, die ein einfaches Objekt statt eines Proxys erwarten.
Runes funktionieren auch in .svelte.js- und .svelte.ts-Dateien, damit kannst du reaktive Logik außerhalb von Komponenten teilen.
Häufige Fragen
Muss ich für Svelte 5 meine ganze App neu schreiben?
Nein. Svelte 5 unterstützt weiterhin die Svelte-4-Syntax, und Komponenten im alten Stil und mit Runes können in derselben App nebeneinander existieren und sich gegenseitig verwenden, sodass du Datei für Datei umstellen kannst.
Warum läuft mein $effect nicht erneut?
Svelte verfolgt nur State, der synchron innerhalb des Effekts gelesen wird. Ein Wert, der nach einem await oder in einem setTimeout-Callback gelesen wird, ist keine Abhängigkeit, und ihn zu ändern bewirkt nichts.
Kann ich einen $derived-Wert ändern?
Seit Svelte 5.25 kannst du einen abgeleiteten Wert vorübergehend neu zuweisen, was bei optimistischen Updates hilft, sofern er nicht mit const deklariert ist. Er wird neu berechnet, wenn sich seine Abhängigkeiten ändern. Frühere Versionen behandeln Deriveds als schreibgeschützt.
Was hat createEventDispatcher ersetzt?
Callback-Props. Die Kindkomponente erhält eine Funktion wie onsave über $props und ruft sie auf, und die Elternkomponente übergibt den Handler wie jedes andere Attribut.
Wie gebe ich einem Formularfeld eine eindeutige ID?
Rufe $props.id() auf, eingeführt in Svelte 5.20. Es gibt eine für die Komponenteninstanz eindeutige ID zurück, die zwischen Server und Browser übereinstimmt, und ist daher sicher für for und aria-labelledby.
$state ist standardmäßig tief
Wenn du ein Array oder ein einfaches Objekt in $state einschließt, bekommst du einen tief reaktiven Proxy. Ein push auf das Array oder das Setzen einer verschachtelten Eigenschaft aktualisiert nur die Teile der Seite, die sie lesen, ohne dass du den ganzen Wert neu zuweisen musst.
Auch Klassenfelder können State sein: Deklariere ein Feld mit $state innerhalb einer Klasse, und der Compiler macht daraus ein Getter-Setter-Paar.
$derived muss pur bleiben
Der Ausdruck in $derived sollte nur rechnen. Svelte verweigert darin State-Änderungen wie count++. Für längere Logik nimmt $derived.by eine Funktion, deren Rückgabewert zum abgeleiteten Wert wird.
Deriveds sind lazy: Svelte markiert sie als veraltet, wenn sich eine Abhängigkeit ändert, und berechnet sie beim nächsten Lesen neu, wobei nachgelagerte Arbeit entfällt, wenn das Ergebnis gleich bleibt.
Timing und Aufräumen bei $effect
Ein Effekt läuft, nachdem die Komponente gemountet ist, und erneut, nachdem sich seine Abhängigkeiten geändert haben, sobald das DOM aktualisiert ist. Gib aus dem Effekt eine Funktion zurück, um Timer oder Listener vor dem nächsten Lauf und beim Zerstören der Komponente aufzuräumen.
Wenn du etwas messen oder anpassen musst, bevor sich das DOM ändert, etwa um einen Chatverlauf unten zu halten, verwende stattdessen $effect.pre.
State zwischen Komponenten teilen
Ein reaktiver Store in einer .svelte.js-Datei
Eine neu zugewiesene $state-Variable lässt sich nicht direkt exportieren, exportiere also ein Objekt und ändere stattdessen seine Eigenschaften.
$state
Ein einfaches let ist im Runes-Modus nicht mehr reaktiv. Schließ den Startwert in $state ein und aktualisiere ihn wie jede Variable.
$derived
Das $:-Label hatte zwei Aufgaben. Berechnungen werden zu $derived; Svelte berechnet sie neu, wenn sich count ändert.
$effect
Seiteneffekte aus $: wandern in $effect. Er läuft im Browser nach dem DOM-Update, und sein Rückgabewert ist das Aufräumen.
$props
Alle Props kommen über eine einzige Destrukturierung an. Standardwerte, Umbenennungen und Rest-Props nutzen normale JavaScript-Syntax.
$bindable
Markiere eine Prop mit $bindable, damit eine Elternkomponente bind: darauf verwenden kann. Der Code der Elternkomponente bleibt gleich.
Events
Aus on:click wird das Attribut onclick, und eigene Events werden zu Callback-Props statt createEventDispatcher.
Snippets
Das children-Snippet ersetzt den Standard-Slot, und {@render} platziert es. Das ?. überspringt das Rendern, wenn keine children übergeben wurden.