🚀 Getting Started
Basic Syntax & Expressions
Svelte allows you to write standard HTML alongside JavaScript inside a <script> tag. Variables and valid JavaScript expressions can be interpolated directly into the markup using curly braces {}.
<script>
let name = 'world';
let firstName = "Zehan";
let lastName = "Khan";
function fullName() {
return `${firstName} ${lastName}`;
}
</script>
<h1>Hello {name}!</h1>
<p>Full name from function: {fullName()}</p>
Attributes & Functions in Markup
HTML attributes can be dynamically bound to Svelte variables, and you can trigger function returns seamlessly.
<script>
let avatarUrl = '[https://example.com/avatar.png](https://example.com/avatar.png)';
</script>
<img src={avatarUrl} alt="Avatar" />
Conditional Rendering
Control what gets rendered using Svelte's built-in block logic.
<script>
let temperature = 24;
let city = "New York";
</script>
{#if temperature >= 20}
<p>It is {temperature}°C (Warm) in {city}</p>
{:else}
<p>It is {temperature}°C in {city}</p>
{/if}
Svelte components must always return a root element or clean content. Unlike React, wrapping fragment tags (<>...</>) are not required.
🧩 Components & Props
Accepting Properties with $props()
In modern Svelte 5, component properties are accepted using the $props() rune, which supports destructuring and default values.
<!-- UserProfile.svelte -->
<script>
let { name = "User", age } = $props();
</script>
<div class="UserProfile">
<div>Hello {name}, you are {age} years old.</div>
</div>
Embedding Components
Import components (internal or external) and render them like self-closing HTML tags.
<script>
import UserProfile from './UserProfile.svelte';
import ThirdPartyChart from 'some-library';
</script>
<UserProfile age="{23}" name="Zehan"/>
<ThirdPartyChart/>
⚡ State & Runes (Svelte 5)
Svelte 5 introduces Runes ($state, $derived, $effect, $props) for explicit, fine-grained reactivity. They replace the older let and $: label syntax for reactive state.
Local State ($state)
Use $state() to declare reactive local variables. When updated, the DOM reacts automatically.
<script>
let name = $state("Zehan");
function updateName() {
name = prompt("What is your name?") || name;
}
</script>
<h1>{name}</h1>
<button onclick={updateName}>Update name</button>
Derived State ($derived)
For values that depend entirely on other state variables, use $derived().
<script>
let a = $state(2);
let b = $state(3);
// sum will automatically update if 'a' or 'b' changes
let sum = $derived(a + b);
</script>
<p>The sum is: {sum}</p>
Side Effects ($effect)
To automatically run code side effects whenever a reactive dependency changes, use the $effect() rune.
<script>
let name = $state('Zehan');
$effect(() => {
console.log('The name state has changed to:', name);
});
</script>
🔄 Logic & Loops
Iterating with {#each}
Svelte provides an {#each} block to iterate over arrays and array of objects.
<script>
let elements = [
{ id: 1, name: "one", value: 10 },
{ id: 2, name: "two", value: 20 }
];
</script>
<ul>
{#each elements as element, index (element.id)}
<li>
Item {index}: The value for {element.name} is {element.value}
</li>
{/each}
</ul>
(Passing an identifier like (element.id) helps Svelte optimize DOM updates).
📝 Forms & Events
Two-Way Data Binding
Use the bind:value directive to tie form inputs to local reactive variables effortlessly.
<script>
let username = $state("");
let password = $state("");
function handleSubmit(event) {
event.preventDefault();
alert(`Logging in with ${username}`);
}
</script>
<form onsubmit={handleSubmit}>
<input type="text" placeholder="Username" bind:value={username} />
<input type="password" placeholder="Password" bind:value={password} />
<button type="submit">Login</button>
</form>
Bind Grouped Inputs
Grouped bindings sync multiple inputs (like radios) back to a single active state.
<script>
let selected = $state('apple');
</script>
<label><input type="radio" bind:group={selected} value="apple" /> Apple</label>
<label><input type="radio" bind:group={selected} value="orange" /> Orange</label>
<p>Selected: {selected}</p>
Event Listeners & Modifiers
Use HTML syntax prefixes (onclick) and chain modifiers (like |preventDefault).
<script>
function handleClick() {
alert("Hello World");
}
</script>
<a href="#" onclick|preventDefault={handleClick}>Say Hi</a>
🎨 Styling & DOM Bindings
Scoped CSS & Directives
Styles inside <style> are automatically scoped to the component. You can also use directives to toggle classes dynamically.
<script>
let isActive = $state(true);
let size = $state(16);
</script>
<!-- Toggles class "active" based on boolean -->
<div class:active={isActive}>Toggle me</div>
<!-- Inline dynamic styles -->
<p style:font-size={`${size}px`}>Resizable text</p>
<style>
.active { color: blue; }
</style>
📡 Fetching Data & Promises
Fetching with Lifecycle Hooks (onMount)
Data loading for side effects can be handled efficiently inside component lifecycle imports.
<script>
import { onMount } from 'svelte';
let notifications = $state([]);
let loading = $state(true);
onMount(async () => {
const res = await fetch("[https://api.example.com/notifications](https://api.example.com/notifications)");
notifications = await res.json();
loading = false;
});
</script>
{#if loading}
<p>Loading notifications...</p>
{:else}
<ul>
{#each notifications as note}
<li>{note.title}</li>
{/each}
</ul>
{/if}
Await Blocks
Handle JavaScript Promises directly in the HTML template markup.
<script>
let userPromise = fetch('[https://jsonplaceholder.typicode.com/users/1](https://jsonplaceholder.typicode.com/users/1)')
.then(res => res.json());
</script>
{#await userPromise}
<p>Loading...</p>
{:then user}
<p>Welcome, {user.name}!</p>
{:catch error}
<p>Error: {error.message}</p>
{/await}
⏳ Lifecycle Hooks
Svelte lifecycle functions are imported individually from svelte.
| Hook | Purpose |
|---|---|
onMount |
Runs after the component is first rendered to the DOM. |
beforeUpdate |
Runs immediately before the DOM updates based on state changes. |
afterUpdate |
Runs immediately after the DOM has updated. |
onDestroy |
Runs immediately before the component is unmounted from the DOM. |
📦 Stores (External State)
While Runes handle component state, Stores are great for external, cross-component communication.
Writable & Derived Stores
// store.js
import { writable, derived } from 'svelte/store';
export const count = writable(0);
export const double = derived(count, ($count) => $count * 2);
Subscribing to Stores in Components
Use the $ prefix in your component template to auto-subscribe and read the store value.
<!-- App.svelte -->
<script>
import { count, double } from './store.js';
</script>
<button onclick={() => $count++}>Increment</button>
<p>Count: {$count}</p>
<p>Double: {$double}</p>
🌐 SvelteKit Server-Side Rendering (SSR)
SvelteKit provides production-ready SSR. Data loaded from a +page.server.js file is passed seamlessly as data into your Svelte page views.
// +page.server.js
export async function load({ fetch }) {
const res = await fetch('/api/data');
const data = await res.json();
return { data }; // Returns to the page as props
}
<!-- +page.svelte -->
<script>
let { data } = $props();
</script>
<h1>{data.title}</h1>






