Chaque rune de Svelte 5 avec le code Svelte 4 qu'elle remplace : $state, $derived, $effect, $props et $bindable, plus la nouvelle syntaxe des événements et des snippets. Des exemples prêts à copier.
Les runes sont les mots-clés du compilateur que Svelte 5 utilise pour la réactivité. $state déclare une variable réactive, $derived calcule une valeur à partir d'autres états, $effect exécute du code après la mise à jour de la page, $props lit les props du composant et $bindable marque une prop à laquelle un parent peut se lier. Elles remplacent le let réactif, le label $: et export let de Svelte 4.
La syntaxe Svelte 4 et la rune qui la remplace
Rôle
Svelte 4
Svelte 5
Variable réactive
let count = 0
let count = $state(0)
Valeur calculée
$: doubled = count * 2
let doubled = $derived(count * 2)
Effet de bord
$: console.log(count)
$effect(() => console.log(count))
Props
export let name
let { name } = $props()
Prop liable
export let value
let { value = $bindable() } = $props()
Gestionnaire d'événement
on:click={fn}
onclick={fn}
Événements de composant
createEventDispatcher
Props de callback
Slots
<slot />
{#snippet} et {@render}
Choisissez une rune pour voir un composant Svelte 4 et sa réécriture en Svelte 5. Chaque paire se comporte de la même façon : vous pouvez donc migrer un fichier à la fois et vérifier le résultat au fur et à mesure.
Sélectionnez une rune ou un changement de syntaxe avec les boutons.
Comparez le code Svelte 4 à gauche avec le code Svelte 5 à droite.
Lisez la note qui explique la règle qui piège souvent.
Copiez la version Svelte 5 dans votre composant.
Utilisez $derived pour tout ce qui peut se calculer. Réservez $effect aux échanges avec ce qui est extérieur à Svelte, comme le titre du document, un canvas ou un widget tiers.
Rappelez-vous que $effect ne s'exécute jamais pendant le rendu serveur : c'est donc un endroit sûr pour le code qui touche à window ou document.
Optez pour $state.raw avec les grands tableaux que vous ne faites que remplacer. Il évite le proxy profond et ne peut être que réassigné.
Passez $state.snapshot(value) aux bibliothèques qui attendent un objet simple plutôt qu'un proxy.
Les runes fonctionnent aussi dans les fichiers .svelte.js et .svelte.ts, ce qui permet de partager de la logique réactive en dehors des composants.
Questions fréquentes
Faut-il réécrire toute mon application pour Svelte 5 ?
Non. Svelte 5 prend toujours en charge la syntaxe de Svelte 4, et les composants à l'ancienne et ceux à base de runes peuvent cohabiter dans la même application et s'utiliser mutuellement : vous pouvez donc convertir les fichiers un par un.
Pourquoi mon $effect ne se relance-t-il pas ?
Svelte ne suit que l'état lu de façon synchrone dans l'effet. Une valeur lue après un await ou dans un callback de setTimeout n'est pas une dépendance : la modifier ne déclenche donc rien.
Peut-on modifier une valeur $derived ?
Depuis Svelte 5.25, vous pouvez réassigner temporairement une valeur dérivée, ce qui aide pour les mises à jour optimistes, sauf si elle est déclarée avec const. Elle se recalcule quand ses dépendances changent. Les versions antérieures traitent les valeurs dérivées en lecture seule.
Qu'est-ce qui remplace createEventDispatcher ?
Les props de callback. L'enfant reçoit une fonction comme onsave via $props et l'appelle, et le parent passe le gestionnaire comme n'importe quel autre attribut.
Comment donner un id unique à un champ de formulaire ?
Appelez $props.id(), ajouté dans Svelte 5.20. Il renvoie un id propre à l'instance du composant, identique côté serveur et navigateur : il est donc sûr pour for et aria-labelledby.
$state est profond par défaut
Envelopper un tableau ou un objet simple dans $state vous donne un proxy réactif en profondeur. Ajouter un élément au tableau ou modifier une propriété imbriquée met à jour uniquement les parties de la page qui la lisent, sans avoir à réassigner toute la valeur.
Les champs de classe peuvent aussi être de l'état : déclarez un champ avec $state dans une classe et le compilateur le transforme en paire getter et setter.
$derived doit rester pur
L'expression dans $derived doit seulement calculer. Svelte refuse les modifications d'état comme count++ à l'intérieur. Pour une logique plus longue, $derived.by prend une fonction dont la valeur de retour devient la valeur dérivée.
Les valeurs dérivées sont paresseuses : Svelte les marque comme obsolètes quand une dépendance change et les recalcule à la lecture suivante, en sautant le travail en aval si le résultat est identique.
Timing et nettoyage de $effect
Un effet s'exécute après le montage du composant, puis à nouveau après le changement de ses dépendances, une fois le DOM mis à jour. Renvoyez une fonction depuis l'effet pour nettoyer les timers ou les listeners avant l'exécution suivante et à la destruction du composant.
Si vous devez mesurer ou ajuster quelque chose avant que le DOM change, par exemple pour garder un fil de discussion défilé tout en bas, utilisez plutôt $effect.pre.
Partager de l'état entre composants
Un store réactif dans un fichier .svelte.js
Une variable $state réassignée ne peut pas être exportée directement : exportez plutôt un objet et modifiez ses propriétés.
$state
Un let simple n'est plus réactif en mode runes. Enveloppez la valeur de départ dans $state et modifiez-la comme n'importe quelle variable.
$derived
Le label $: avait deux rôles. Les calculs deviennent des $derived ; Svelte les recalcule quand count change.
$effect
Les effets de bord de $: passent dans $effect. Il s'exécute dans le navigateur après la mise à jour du DOM, et sa valeur de retour sert au nettoyage.
$props
Toutes les props arrivent via une seule instruction de déstructuration. Valeurs par défaut, renommages et props rest utilisent la syntaxe JavaScript normale.
$bindable
Marquez une prop avec $bindable pour qu'un parent puisse utiliser bind: dessus. Le code du parent reste le même.
Événements
on:click devient l'attribut onclick, et les événements personnalisés deviennent des props de callback au lieu de createEventDispatcher.
Snippets
Le snippet children remplace le slot par défaut, et {@render} le place. Le ?. évite le rendu quand aucun enfant n'a été passé.