Svelte logoSveltev5INTERMEDIATE

Svelte

Svelte 5 cheat sheet covering runes, snippets, reactivity, components, stores, and SvelteKit integration with practical code examples.

15 min read
svelte5runessveltekitreactiveframework

Other Svelte Sheets

Sign in to mark items as known and track your progress.

Sign in

Setup & Basics

Getting started with Svelte 5 and core concepts

Installation

Setting up a new Svelte 5 project

bash
# Quick Start
npm create vite@latest my-app -- --template svelte
cd my-app && npm install && npm run dev
💡 Svelte 5 compiles components to vanilla JavaScript
⚡ No virtual DOM - direct DOM manipulation for speed
📦 Smaller bundle sizes than most frameworks
🔧 Built-in state management with new runes system

Component Structure

Basic Svelte component anatomy

javascript
<!-- MyComponent.svelte -->
<script>
  let message = 'Hello Svelte';
</script>

<h1>{message}</h1>

<style>
  h1 { color: #ff3e00; }
</style>
🎨 Styles are scoped to component by default
📝 No JSX - write regular HTML with enhancements
🔒 TypeScript support with lang="ts" attribute
⚡ Components compile to efficient JavaScript

Runes (Svelte 5)

New reactive primitives in Svelte 5

$state

Reactive state management rune

javascript
<script>
  // Simple state
  let count = $state(0);
  
  // Object state
  let user = $state({ name: 'Alice', age: 25 });
  
  // Array state
  let todos = $state([]);
</script>

<button onclick={() => count++}>
  Count: {count}
</button>
🎯 Replaces let declarations for reactive state
🔄 Deep reactivity for objects and arrays automatically
📦 Works with classes and complex structures
⚡ Fine-grained reactivity with minimal re-renders

$derived

Computed values from state

javascript
<script>
  let count = $state(0);
  
  // Simple derived
  const doubled = $derived(count * 2);
  
  // Object derived
  const stats = $derived({
    count,
    doubled: count * 2,
    isEven: count % 2 === 0
  });
</script>

<p>Count: {count}, Doubled: {doubled}</p>
🔄 Auto-updates when dependencies change
📊 Perfect for calculated values and statistics
🎯 Replaces $: reactive statements from Svelte 4
⚡ Cached and optimized automatically

$effect

Side effects and lifecycle

javascript
<script>
  import { untrack } from 'svelte';
  
  let count = $state(0);
  
  // Simple effect
  $effect(() => {
    console.log('Count:', count);
  });
  
  // Effect with cleanup
  $effect(() => {
    const timer = setInterval(() => {
      console.log('Tick');
    }, 1000);
    
    return () => clearInterval(timer);
  });
</script>
🔄 Replaces onMount, afterUpdate, and onDestroy
🧹 Return cleanup function for teardown logic
📍 $effect.pre runs before DOM updates
🎯 untrack() prevents dependency tracking

Advanced Runes ($state.raw, $derived.by, $inspect)

Opt out of deep reactivity, derive with a function, debug reactive values

svelte
<script>
  // $state.raw — skip deep proxy wrapping (huge perf win for big arrays/objects)
  let rows = $state.raw([])
  // Must replace the whole reference; mutating in place won't trigger updates:
  rows = [...rows, newRow]    // ✓
  // rows.push(newRow)         // ✗ — no reactivity

  // $derived.by — function form for multi-statement derivations
  let stats = $derived.by(() => {
    const total = rows.length
    const active = rows.filter(r => r.active).length
    return { total, active, ratio: total ? active / total : 0 }
  })

  // $inspect — log a reactive value (dev-only)
  $inspect(rows)
  $inspect(stats).with((type, value) => {
    if (type === 'update') console.log('stats changed', value)
  })
</script>
💡 $state.raw skips the Proxy — big perf win when you only swap references
📌 Use $derived.by for multi-statement derivations; $derived for one-liners
⚡ $inspect is stripped at build time — leave it in dev code freely
🎯 $state.snapshot(x) gives you a plain object for fetch/JSON.stringify
runessvelte5reactivitydebugging

Control Flow

Conditional rendering and loops

If/Else Blocks

Conditional rendering

javascript
{#if loggedIn}
  <p>Welcome back!</p>
{:else}
  <p>Please log in</p>
{/if}

{#if score >= 90}
  <p>A</p>
{:else if score >= 80}
  <p>B</p>
{:else}
  <p>F</p>
{/if}
🎯 {#if} blocks for conditional rendering
🔄 {:else if} for multiple conditions
📦 Can nest if blocks for complex logic
⚡ Efficient DOM updates with block-level reactivity

Each Blocks

Rendering lists and arrays

javascript
{#each items as item}
  <li>{item.name}</li>
{/each}

{#each items as item, index}
  <li>{index + 1}. {item.name}</li>
{/each}

{#each items as item (item.id)}
  <li>{item.name}</li>
{/each}
🔄 {#each} for rendering lists and arrays
🔑 (key) for keyed updates and animations
📝 {:else} for empty state handling
⚡ Efficient list reconciliation with keys

Stores

Global state management

Writable Stores

Creating and using writable stores

javascript
// stores.js
import { writable } from 'svelte/store';

export const count = writable(0);
export const user = writable({ name: 'Guest' });

// Component.svelte
<script>
  import { count } from './stores.js';
</script>

<button onclick={() => $count++}>
  Count: {$count}
</button>
📦 Global state accessible from any component
$ Auto-subscription with automatic cleanup
🔄 update() for transforming current value
💾 Can persist to localStorage easily

Derived & Readable

Computed and read-only stores

javascript
// stores.js
import { readable, derived } from 'svelte/store';

// Readable store
export const time = readable(new Date(), (set) => {
  const interval = setInterval(() => {
    set(new Date());
  }, 1000);
  
  return () => clearInterval(interval);
});

// Derived store
export const doubled = derived(count, $count => $count * 2);
📊 derived() for computed values from stores
🔒 readable() for read-only external data
⚡ Async derived with set callback
🧮 Complex calculations update automatically

SvelteKit

Full-stack framework for Svelte

Routing

File-based routing in SvelteKit

javascript
// File structure
src/routes/
  +page.svelte       // index (/)
  +layout.svelte     // root layout
  about/
    +page.svelte     // /about
  blog/
    [slug]/
      +page.svelte   // /blog/:slug
📁 File-based routing with special files
🎯 Dynamic routes with [param] syntax
📦 Route groups with (name) for organization
🔄 Load functions for data fetching

Props & Bindings

Component props and data binding

$props

Component props in Svelte 5

javascript
<script>
  // Basic props
  let { name, age } = $props();
  
  // With defaults
  let { 
    title = 'Default',
    count = 0 
  } = $props();
</script>

<h1>{title}</h1>
<p>{name} is {age}</p>
🎯 Replaces export let declarations from Svelte 4
📦 Destructure all props at once for cleaner code
🔧 Full TypeScript support with generics
⚡ Props are reactive by default

$bindable

Two-way binding for props

javascript
<!-- Child.svelte -->
<script>
  let { value = $bindable() } = $props();
</script>

<input bind:value />

<!-- Parent.svelte -->
<script>
  import Child from './Child.svelte';
  let text = $state('');
</script>

<Child bind:value={text} />
<p>Parent sees: {text}</p>
🔄 Enables two-way data binding between components
📤 Child can update parent state directly
🎯 Replaces bind:prop directive pattern
⚡ Works seamlessly with $state in parent

Form Bindings

Two-way data binding with form elements

javascript
<script>
  let text = $state('');
  let checked = $state(false);
  let selected = $state('opt1');
  let files = $state();
</script>

<input bind:value={text} />
<input type="checkbox" bind:checked />
<select bind:value={selected}>
  <option value="opt1">Option 1</option>
  <option value="opt2">Option 2</option>
</select>
<input type="file" bind:files />
🔄 bind:value for text and number inputs
☑️ bind:checked for single checkboxes
📝 bind:group for radio and checkbox groups
📁 bind:files for file uploads with FileList

Snippets (Svelte 5)

Reusable template fragments (replaces slots)

Basic Snippets

Creating and using snippets

javascript
{#snippet greeting(name)}
  <p>Hello, {name}!</p>
{/snippet}

{@render greeting('World')}
{@render greeting('Svelte')}
🎯 Replaces slots in Svelte 5
📦 Reusable template fragments within component
🔄 Can pass multiple parameters
⚡ More flexible and powerful than slots

Component Snippets

Passing snippets between components

javascript
<!-- Card.svelte -->
<script>
  let { header, children, footer } = $props();
</script>

<div class="card">
  {@render header?.()}
  {@render children()}
  {@render footer?.()}
</div>

<!-- Usage -->
<Card>
  {#snippet header()}
    <h2>Title</h2>
  {/snippet}
  
  {#snippet children()}
    <p>Content</p>
  {/snippet}
</Card>
📤 Pass snippets as props to components
🎰 Named snippet props for organization
🔄 Children is the default snippet
📦 Replaces slot and slot prop patterns

Events & Actions

Event handling and element actions

Event Handlers

Handling DOM events in Svelte 5

javascript
<script>
  let count = $state(0);
  
  function handleClick() {
    count++;
  }
</script>

<button onclick={handleClick}>
  Count: {count}
</button>

<button onclick={() => count++}>
  Increment
</button>
🎯 Use onclick, onsubmit, etc. (lowercase) in Svelte 5
📝 Access event object in handler functions
🔄 No automatic preventDefault - must call manually
⚡ Direct event binding for better performance

Actions

Reusable element behaviors

javascript
<script>
  function tooltip(node, text) {
    // Setup
    // Return { update, destroy }
  }
</script>

<button use:tooltip={'Hover me'}>
  Button
</button>
🎯 use:action directive for reusable behaviors
🔄 Update function for reactive parameters
🧹 Destroy function for cleanup
📦 Encapsulate complex DOM interactions

Transitions & Animations

Built-in transitions and animations

Built-in Transitions

Svelte built-in transition functions

javascript
<script>
  import { fade, fly, slide } from 'svelte/transition';
  let visible = $state(true);
</script>

{#if visible}
  <div transition:fade>
    Fades in and out
  </div>
  
  <div transition:fly={{ x: 200 }}>
    Flies in from right
  </div>
  
  <div transition:slide>
    Slides down
  </div>
{/if}
🎭 Built-in transitions: fade, fly, slide, scale, blur, draw
⚡ Automatic animation on element mount/unmount
🎨 Customizable duration, delay, easing functions
🔄 Different in/out transitions supported

Custom Transitions

Creating custom transition functions

javascript
<script>
  function typewriter(node, { speed = 1 }) {
    const text = node.textContent;
    const duration = text.length / (speed * 0.01);
    
    return {
      duration,
      tick: t => {
        const i = Math.trunc(text.length * t);
        node.textContent = text.slice(0, i);
      }
    };
  }
</script>

{#if visible}
  <p transition:typewriter>
    Hello World!
  </p>
{/if}
🎨 Create custom transitions with CSS or tick functions
📊 CSS-based transitions are GPU-accelerated
🔧 Tick function for JavaScript-based animations
⚡ Return duration, css, or tick properties

Special Elements

Svelte special elements and components

Special Elements

Svelte special elements for advanced use cases

javascript
<!-- Bind to window -->
<svelte:window 
  onresize={handleResize}
  onscroll={handleScroll}
/>

<!-- Dynamic component -->
<svelte:component this={ComponentName} />

<!-- Bind to body -->
<svelte:body onclick={handleClick} />

<!-- Insert into head -->
<svelte:head>
  <title>Page Title</title>
</svelte:head>
🪟 svelte:window for global window events
🔄 svelte:component for dynamic component rendering
📄 svelte:head to insert elements into document head
🎯 svelte:element for dynamic HTML elements

More Svelte Cheat Sheets