# Le runes di Svelte 5: stato, derivati ed effetti

Le runes sostituiscono le assegnazioni magiche di Svelte 4: state per lo stato, derived per i calcoli, effect solo per il DOM e le API esterne.

> Pagina: https://ui.eneawork.it/blog/svelte-5-runes-guida
> Markdown: https://ui.eneawork.it/blog/svelte-5-runes-guida.md

*2026-11-01*

In Svelte 5 lo stato si dichiara con $state: la rune è una chiamata che il compilatore riconosce, non un let di cui indovina il ruolo. Da quella chiamata il compilatore sa cosa tracciare e cosa lasciare fermo.

## Quattro runes coprono quasi tutto

$state per lo stato mutabile, $derived per i valori calcolati, $effect per gli effetti collaterali, $props per gli input del componente. $bindable, $inspect e $host servono in casi più stretti.

npx sv migrate svelte-5

let { start = 0 }: { start?: number } = $props(); let count = $state(start); const double = $derived(count * 2); (count += 1)}>Add one {count} × 2 = {double}

$state avvolge oggetti e array in un proxy: le modifiche annidate sono tracciate. Per dati grandi che sostituisci in blocco c’è $state.raw; per passare un oggetto a una libreria esterna usa $state.snapshot, che restituisce una copia semplice.

## Derived non è un effetto

$derived dichiara un valore, $derived.by accetta un blocco di codice. $effect gira dopo l’aggiornamento del DOM, solo nel browser, e serve per il DOM o per API esterne: usarlo per allineare due stati produce un ciclo che il compilatore non ti segnala.

let query = $state(""); let items = $state([]); const matches = $derived.by(() => items.filter((item) => item.name.toLowerCase().includes(query.toLowerCase())), ); $effect(() => { document.title = matches.length + " results"; });

## Props con $props e $bindable

let { title, value = 0 } = $props() dichiara gli input e i loro default. $bindable() rende una prop scrivibile da fuori: senza, l’assegnazione resta locale al figlio e il genitore non vede il cambio.

Misurato il 1 novembre 2026: su 1.514 profili di libreria del catalogo 3 riguardano Svelte e 2 dichiarano licenza MIT, flowbite-svelte e shadcn-svelte; svelte-bits rimanda al sito del progetto (1 novembre 2026). Metodo: conteggio dei campi id e license di data/library_profiles.json con uno script Node, sul repository EneUI.

## Il limite da mettere in conto

Le runes esistono solo dove il compilatore le vede: nei file .svelte e in quelli con suffisso .svelte.ts. Un modulo .ts normale non può contenere $state, e $effect non gira durante il rendering sul server.

## Errori che si vedono nella migrazione

I componenti Svelte del catalogo sono già in questa forma: flowbite-svelte e svelte-bits si installano come sorgente, e il blocco form mostra il caso in cui lo stato locale basta. Il routing è in routing e layout in SvelteKit, il vecchio modello di store in store che non si aggiorna, il confronto in Svelte vs React.

## FAQ

### Devo riscrivere tutti i componenti?

No. La modalità runes si attiva per componente e Svelte 5 compila ancora la sintassi vecchia. Riscrivi dove lo stato diventa difficile da seguire, non tutto in una volta.

### $state o $state.raw?

$state per strutture che modifichi in profondità, raw per array e oggetti grandi che sostituisci in blocco. Raw non traccia le modifiche interne: riassegna il valore.

### Perché $effect gira più volte?

Perché il primo giro registra le dipendenze e i successivi applicano il risultato. Se i giri sono troppi, l’effetto legge e scrive lo stesso stato: sposta il calcolo in un derivato.

### Le runes funzionano in un file .ts?

Solo con il suffisso .svelte.ts, che passa dal compilatore. Un file .ts normale non viene processato e la rune resta una chiamata a una funzione che non esiste.

### Svelte 5 è compatibile con le librerie Svelte 4?

In gran parte sì: i componenti vecchi continuano a compilare in modalità legacy. Il rischio sono le azioni che dipendono da this e i binding impliciti, che nelle runes non esistono più.
