How does Svelte 5's reactivity model with $state differ from Svelte 4?

Answer

Svelte 5 uses an explicit fine-grained reactivity system based on signals (similar to Solid.js), unlike Svelte 4's compile-time implicit reactivity. Svelte 4: the compiler tracks which variables are used in templates and wraps assignments with invalidation calls. Works automatically but is limited — reactive logic cannot be extracted into plain .js files. Svelte 5: $state() creates a reactive state object that uses JavaScript Proxy at runtime. Deep reactivity: let user = $state({ name: 'Alice', address: { city: 'NY' } }) — mutating user.address.city = 'LA' is reactive without reassignment. Reactive logic can live in .svelte.js files and be imported anywhere. $derived.by(): for complex derived computations: let sorted = $derived.by(() => [...items].sort()). The key improvement: runes make reactivity portable beyond .svelte files — write reusable reactive classes and functions in regular TypeScript.