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

Loading your progress

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

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

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

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

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

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

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

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