Svelte Reference & Cheatsheet
Svelte Reference & Cheatsheet
Svelte is a radical JavaScript framework that shifts work from the browser to the compiler, converting declarative components into efficient imperative code at build time for blazing-fast apps.
What You’ll Learn
- How Svelte’s component syntax differs from React and Vue
- How reactive declarations (
$:) keep your UI in sync with data - How stores manage shared state across components
- How bindings create two-way connections between data and UI
- How transitions, slots, and lifecycle functions work
Why Svelte Matters
Svelte introduces a unique concept: the framework disappears at runtime. Instead of sending a framework library to the browser (like React or Vue), Svelte compiles your code into vanilla JavaScript during build. The result is smaller bundles, faster page loads, and less memory usage. This efficiency is why tools like Durga Antivirus Pro can build real-time scanning dashboards that update instantly without browser lag. DodaTech chose Svelte’s philosophy of “write less, do more” because it aligns with building fast, lightweight applications.
Security note: Understanding Reference helps build more secure applications — a core principle at DodaTech, where tools like Durga Antivirus Pro and Doda Browser rely on solid implementation practices.
flowchart LR
A[JavaScript Fundamentals] --> B[Svelte Basics]
B --> C[Components & Props]
B --> D[Reactive Declarations]
C --> E[Bindings & Events]
D --> E
E --> F[Stores & State Management]
E --> G[Transitions & Animation]
F --> H[SvelteKit / Full Apps]
style B fill:#4a90d9,color:#fff
Component Syntax — The Svelte Way
A Svelte component is a single .svelte file containing all three web technologies: HTML, CSS, and JavaScript. Think of it as a self-contained module — everything a UI piece needs lives in one file.
<script>
// export makes this a prop — the parent can pass a value
export let name = "World";
// Local state: just declare a variable
let count = 0;
// Reactive declaration: $: means "recompute when dependencies change"
$: doubled = count * 2;
// Reactive statement: runs whenever count changes
$: console.log("count changed:", count);
function handleClick() {
count += 1; // Svelte knows count changed and updates the DOM
}
</script>
<!-- Curly braces evaluate JavaScript expressions -->
<h1>Hello {name}!</h1>
<!-- on:click is Svelte's event syntax -->
<button on:click={handleClick}>
Clicked {count} times (doubled: {doubled})
</button>
<style>
/* Scoped by default — these styles won't leak to other components */
h1 { color: purple; }
button { font-size: 1.2rem; }
</style>Why this matters: In React, you’d need useState, a separate JSX file, and probably a CSS-in-JS library. In Svelte, it’s all in one file. The <style> is scoped automatically — no class name conflicts, no CSS modules setup.
Reactive Declarations
The $: syntax is Svelte’s reactive declaration. It tells Svelte “watch the variables on the right side, and re-run the code on the left when they change.”
<script>
let a = 1;
let b = 2;
// Recomputed whenever a or b changes
$: sum = a + b;
// Also works with functions
$: largest = Math.max(a, b);
// Block reactive statement — runs code when condition changes
$: if (sum > 10) {
console.log("Large sum!");
}
</script>Line by line: $: sum = a + b creates a derived value. If a becomes 5, sum automatically becomes 7. You don’t need to call a setter or dispatch an event — Svelte tracks the dependencies and updates the DOM for you.
Stores — Shared State
When multiple components need to share the same data (like a user’s login status), you use a store. A store is an external module that holds state and notifies subscribers when it changes.
// stores.js — can be imported by any component
import { writable, derived, readable } from "svelte/store";
// writable: a value that can be changed
export const count = writable(0);
// derived: computed from another store (like a computed property)
export const doubled = derived(count, $count => $count * 2);
// readable: a value that can't be changed from outside
export const time = readable(new Date(), set => {
// This function runs when the first subscriber connects
const interval = setInterval(() => set(new Date()), 1000);
// This cleanup runs when the last subscriber disconnects
return () => clearInterval(interval);
});<!-- Usage in a component -->
<script>
import { count, doubled } from "./stores.js";
// $ prefix auto-subscribes — count.value becomes $count
function reset() {
count.set(0); // Set a new value directly
}
</script>
<p>Count: {$count}</p>
<p>Doubled: {$doubled}</p>
<button on:click={() => count.update(n => n + 1)}>+</button>
<button on:click={reset}>Reset</button>Why stores: Without stores, you’d need to pass props through multiple levels of components (“prop drilling”). Stores give any component direct access to shared state — like a global variable that automatically updates the UI.
Bindings — Two-Way Connections
Bindings create a two-way link between a variable and a form element. Change the variable, the input updates. Type in the input, the variable updates.
<!-- bind:value syncs the variable with the input's value -->
<input bind:value={name} />
<!-- Checkbox binding works with boolean variables -->
<input type="checkbox" bind:checked={isActive} />
<!-- Select dropdowns work the same way -->
<select bind:value={selected}>
<option value="a">A</option>
<option value="b">B</option>
</select>
<!-- Parent-child component binding -->
<Child bind:propName={parentValue} />Why bindings: Without bindings, you’d write on:input handlers and read event.target.value manually. Bindings eliminate that boilerplate — Svelte handles the synchronization for you.
Lifecycle Functions
Svelte gives you hooks into the component’s lifecycle — moments when your component is created, mounts in the DOM, updates, or is destroyed.
<script>
import {
onMount, // Runs after component is first rendered
onDestroy, // Runs when component is removed from DOM
beforeUpdate, // Runs before DOM updates
afterUpdate, // Runs after DOM updates
tick // Returns a promise that resolves after next DOM update
} from "svelte";
onMount(() => {
console.log("Component is now in the DOM");
// Good place to start timers or fetch data
});
onDestroy(() => {
console.log("Component is being removed");
// Cleanup: clear intervals, cancel fetch requests
});
</script>Transitions — Animated UI
Svelte includes built-in transition functions that animate elements when they enter or leave the DOM.
<script>
import { fade, fly, slide, scale } from "svelte/transition";
let visible = false;
</script>
<button on:click={() => visible = !visible}>Toggle</button>
{#if visible}
<!-- transition:fade — fades in/out over 500ms -->
<div transition:fade={{ duration: 500 }}>Fade</div>
<!-- in:fly / out:slide — different animation for enter vs exit -->
<div in:fly={{ x: 200, duration: 300 }} out:slide>Fly in, slide out</div>
{/if}Line by line: The transition: directive applies an animation. fade changes opacity. fly moves the element while fading. You pass options like duration (milliseconds) and x (start position in pixels). The same element gets differing enter (in:) and exit (out:) animations.
Slots — Content Projection
Slots let you create reusable component shells that accept any content from the parent — like a placeholder where the parent’s markup goes.
<!-- Card.svelte — a reusable wrapper component -->
<div class="card">
<!-- Named slot: parent provides content via slot="header" -->
<slot name="header">Default Header</slot>
<!-- Default slot: unnamed, captures everything else -->
<slot />
</div>
<!-- Usage in another component -->
<Card>
<!-- This goes into the "header" slot -->
<h1 slot="header">Custom Header</h1>
<!-- This goes into the default slot -->
<p>Body content</p>
</Card>Why slots: Without slots, you’d need to pass HTML as props (which breaks formatting) or create separate components for every variation. Slots keep your components flexible and your code DRY (Don’t Repeat Yourself).
Common Mistakes
Forgetting the
$prefix for store values:countis the store object.$countis the current value. Using{count}in your template won’t show the value or react to changes.Mutating arrays instead of reassigning:
items.push(newItem)won’t trigger reactivity. Instead, useitems = [...items, newItem]to create a new array.Using
on:clickon a custom component: Event listeners needon:followed by the DOM event name. For custom component events, useon:messagewheremessageis dispatched viacreateEventDispatcher.Not cleaning up in
onDestroy: If you set an interval inonMountbut don’t clear it inonDestroy, the interval continues running even after the component is gone — causing memory leaks.Overusing stores for local state: Not everything needs a store. If only one component uses the data, just use a local variable. Stores are for shared state across unrelated components.
Practice Questions
What does the
$:prefix do in Svelte? It creates a reactive declaration. The code after$:re-runs whenever its dependencies change, automatically updating the DOM.How does Svelte differ from React in terms of bundle size? Svelte compiles your code at build time into vanilla JavaScript with no framework runtime in the bundle. React sends the React library to the browser, which adds ~40KB to the bundle.
When would you use a
writablestore vs aderivedstore?writablestores contain values that can be changed directly (like a counter).derivedstores compute values from other stores automatically (like a running total).What is the difference between
transition:andin:/out:?transition:applies the same animation for both enter and exit.in:only plays on enter.out:only plays on exit.Why are component styles automatically scoped in Svelte? Svelte adds a unique class to each component’s elements and rewrites the CSS selectors to include that class — preventing style conflicts between components.
Challenge
Build a reactive todo list: Create a Svelte component with an input field bound to a variable, a button that adds items to an array, a {#each} loop to display items, and a checkbox binding to mark items as done. Add a writable store to persist the count of incomplete items across components.
FAQ
Try It Yourself
Create a simple Svelte component in the Svelte REPL:
<script>
let name = "";
let items = ["Learn Svelte", "Build an app"];
function addItem() {
if (name.trim()) {
items = [...items, name];
name = "";
}
}
</script>
<h1>Quick List</h1>
<input bind:value={name} placeholder="Add an item..." />
<button on:click={addItem}>Add</button>
<ul>
{#each items as item, i}
<li>{i + 1}. {item}</li>
{/each}
</ul>
<style>
:global(body) { font-family: sans-serif; }
.completed { text-decoration: line-through; }
</style>Expected output: A page with an input field, an “Add” button, and a list that grows as you add items. The bind:value keeps the input in sync with name, and {#each} renders the list reactively.
What’s Next
| Topic | Description |
|---|---|
| Compare Svelte’s reactivity with Vue’s | |
| See how React handles the same problems differently | |
| Add types to your Svelte components |
Related terms: JavaScript, HTML, CSS, Node.js, TypeScript
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro