$state — Reactive State
In React you declare state with useState and always update it through a setter function — you never modify the state variable directly. Svelte 5 flips this completely: $state gives you a plain variable that you mutate directly. The compiler rewrites it behind the scenes into signals, so the UI stays in sync automatically.
Declaring and updating state
Section titled “Declaring and updating state”function Counter() { const [count, setCount] = React.useState(0);
return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(count + 1)}>+1</button> <button onClick={() => setCount(0)}>Reset</button> </div> );}<script> let count = $state(0);</script>
<p>Count: {count}</p><button onclick={() => count++}>+1</button><button onclick={() => count = 0}>Reset</button>There is no setCount. You write count++ or count = 0 directly — exactly what you would do with a plain JavaScript variable.
Deep reactivity: objects and arrays
Section titled “Deep reactivity: objects and arrays”React’s useState is shallow — you must spread objects or replace arrays to trigger a re-render. $state is deeply reactive: mutating a nested property or calling array.push() updates the UI automatically.
function Profile() { const [user, setUser] = React.useState({ name: 'Alice', age: 30 }); const [tags, setTags] = React.useState(['svelte', 'react']);
function birthday() { setUser(u => ({ ...u, age: u.age + 1 })); } function addTag() { setTags(t => [...t, 'js']); }
return ( <div> <p>{user.name} is {user.age}</p> <button onClick={birthday}>Birthday</button> <p>{tags.join(', ')}</p> <button onClick={addTag}>Add tag</button> </div> );}<script> let user = $state({ name: 'Alice', age: 30 }); let tags = $state(['svelte', 'react']);</script>
<p>{user.name} is {user.age}</p><button onclick={() => user.age++}>Birthday</button>
<p>{tags.join(', ')}</p><button onclick={() => tags.push('js')}>Add tag</button>user.age++ and tags.push('js') just work. No spreading, no replacing — Svelte’s proxy-based deep reactivity handles it.
Multiple state variables
Section titled “Multiple state variables”function Form() { const [name, setName] = React.useState(''); const [email, setEmail] = React.useState(''); const [submitted, setSubmitted] = React.useState(false);
function submit() { setSubmitted(true); }
if (submitted) return <p>Sent! Hello, {name}.</p>; return ( <form onSubmit={e => { e.preventDefault(); submit(); }}> <input value={name} onChange={e => setName(e.target.value)} placeholder="Name" /> <input value={email} onChange={e => setEmail(e.target.value)} placeholder="Email" /> <button type="submit">Send</button> </form> );}<script> let name = $state(''); let email = $state(''); let submitted = $state(false);</script>
{#if submitted} <p>Sent! Hello, {name}.</p>{:else} <form onsubmit={e => { e.preventDefault(); submitted = true; }}> <input bind:value={name} placeholder="Name" /> <input bind:value={email} placeholder="Email" /> <button type="submit">Send</button> </form>{/if}