Introduction — Why Svelte for React Developers
You already know React. You understand components, props, state, and the render cycle. Svelte builds on those same ideas but solves them differently — as a compiler rather than a runtime library. This course shows you exactly what changes, what stays familiar, and how to carry your React intuition into Svelte 5.
Svelte is a compiler, not a runtime
Section titled “Svelte is a compiler, not a runtime”React ships a JavaScript runtime (~45 kB gzip for React + ReactDOM) that runs in the browser and manages a virtual DOM tree. Every setState call triggers a reconciliation pass: React diffs the new vDOM against the previous one and patches the real DOM.
Svelte works at build time. Your .svelte files are compiled into tight, framework-free JavaScript that talks directly to the DOM. There is no virtual DOM to diff, no reconciler to ship. The output is plain document.createElement and targeted element.textContent = assignments — the absolute minimum the browser needs.
Practical consequences:
- Smaller bundles. A Svelte app ships almost no framework overhead. A “Hello World” Svelte component compiles to a few hundred bytes.
- Faster updates. Instead of diffing a vDOM tree, compiled Svelte code directly updates only the DOM nodes that actually changed.
- No React import needed. Your components are standalone compiled modules.
Less boilerplate
Section titled “Less boilerplate”React requires explicit state declarations (useState) and a separate setter function for every piece of reactive state. In Svelte 5 you declare reactive state with $state() and mutate it with plain assignment — the compiler instruments the mutation for you.
function Greeting() { const [name, setName] = React.useState('World'); return ( <div> <input value={name} onChange={e => setName(e.target.value)} /> <p>Hello, {name}!</p> </div> );}<script> let name = $state('World');</script>
<input bind:value={name} /><p>Hello, {name}!</p>Notice what disappears in the Svelte version:
- No
useStateimport, no setter function (setName). nameis declared once with$state()— assigning to it is enough to trigger a re-render.bind:valuehandles the two-way sync between the input and the variable (noonChangewiring).
Scoped styles built in
Section titled “Scoped styles built in”React has no opinion on CSS. Teams reach for CSS Modules, styled-components, Tailwind, or some combination. Svelte ships scoped styles as a first-class language feature: a <style> block inside a .svelte file is automatically scoped to that component. No extra tooling, no class name mangling configuration, no runtime overhead.
<style> /* This rule only affects <p> tags inside THIS component */ p { color: steelblue; font-size: 1.2rem; }</style>At compile time Svelte generates a unique attribute (e.g. svelte-abc123) and rewrites the selector to p[svelte-abc123]. Global styles never leak in; your styles never leak out.
Course overview
Section titled “Course overview”| Module | Topics |
|---|---|
| Intro | Compiler model, reactivity basics, scoped styles |
| Components | Props, events, slots/snippets, lifecycle |
| Reactivity | $state, $derived, $effect, stores |
| Bindings | bind:value, bind:checked, bind:this |
| Control Flow | {#if}, {#each}, {#await}, {#key} |
| Styling | Scoped styles, global styles, CSS variables, transitions |
| Routing | SvelteKit pages, layouts, load functions |
| Advanced | Context API, actions, custom stores, TypeScript |
Your first Svelte 5 component
Section titled “Your first Svelte 5 component”function App() { const [name, setName] = React.useState('React developer'); const [count, setCount] = React.useState(0); return ( <div> <input value={name} onChange={e => setName(e.target.value)} /> <p>Hello, {name}!</p> <button onClick={() => setCount(c => c + 1)}> Clicked {count} {count === 1 ? 'time' : 'times'} </button> </div> );}<script> let name = $state('Svelte developer'); let count = $state(0);</script>
<input bind:value={name} /><p>Hello, {name}!</p><button onclick={() => count++}> Clicked {count} {count === 1 ? 'time' : 'times'}</button>Try it live
Section titled “Try it live”The playground below is a complete, editable Svelte 5 component. Change the name, click the button, tweak the styles — everything runs in your browser.