Events
React invented synthetic events with camelCase handler props (onClick, onChange, onSubmit). Svelte 5 drops the special syntax entirely — event handlers are just lowercase HTML attributes, the same names the browser uses (onclick, oninput, onsubmit). If you know how to write an onclick attribute in a plain HTML file, you already know Svelte events.
Click handler
Section titled “Click handler”function Counter() { const [count, setCount] = React.useState(0); return ( <button onClick={() => setCount(c => c + 1)}> Count: {count} </button> );}<script> let count = $state(0);</script>
<button onclick={() => count++}> Count: {count}</button>Key points:
- React:
onClick(capital O, capital C). Svelte 5:onclick(all lowercase). - React needs a setter function from
useState. Svelte 5 mutates$statedirectly —count++just works. - In Svelte 5 the old
on:clickdirective from Svelte 4 is gone. Always use lowercaseonclick.
Named handler functions
Section titled “Named handler functions”Inline arrow functions are fine for simple cases. Extract to a named function for readability:
function Form() { const [value, setValue] = React.useState(''); function handleChange(e) { setValue(e.target.value); } return <input value={value} onChange={handleChange} />;}<script> let value = $state(''); function handleInput(e) { value = e.target.value; }</script>
<input {value} oninput={handleInput} />Note: for two-way binding of inputs, bind:value is cleaner (covered in the Bindings lesson). The named handler pattern is shown here because it maps directly to the React onChange pattern.
The event object
Section titled “The event object”You have full access to the native DOM event — no synthetic wrapper:
function KeyLogger() { const [key, setKey] = React.useState(''); return ( <input onKeyDown={e => setKey(e.key)} placeholder="Press a key" /> );}<script> let key = $state('');</script>
<input onkeydown={e => (key = e.key)} placeholder="Press a key"/>{#if key} <p>Last key: <kbd>{key}</kbd></p>{/if}