📋 Cheat Sheets

Svelte Cheat Sheet — Reactivity, Components, Stores, and Lifecycle


Click any item to expand the explanation and examples.

⚡ Reactivity (Svelte 5 Runes)

$state — reactive variable runes
<script>
  let count = $state(0);
  let user = $state({ name: 'Alice', age: 30 });
</script>

<button onclick={() => count++}>{count}</button>
<p>{user.name}</p>

$state makes a variable reactive. When it changes, the UI updates automatically.

$derived — computed values runes
<script>
  let count = $state(0);
  let doubled = $derived(count * 2);
  let items = $state([1, 2, 3]);
  let total = $derived(items.reduce((a, b) => a + b, 0));
</script>

<p>{count} × 2 = {doubled}</p>

$derived recomputes automatically when its dependencies change.

$effect — side effects runes
<script>
  let query = $state('');

  $effect(() => {
    // Runs when query changes
    console.log('Searching for:', query);
    // Cleanup (optional)
    return () => console.log('Cleanup');
  });
</script>

🧩 Components & Props

$props — component props components
<!-- Button.svelte -->
<script>
  let { label, onclick, variant = 'primary' } = $props();
</script>

<button class={variant} {onclick}>{label}</button>

<!-- Usage -->
<Button label="Click me" onclick={() => alert('hi')} />
{#if}, {#each}, {#await} template
{#if loggedIn}
  <p>Welcome back!</p>
{:else}
  <p>Please log in</p>
{/if}

{#each items as item, index (item.id)}
  <li>{index}: {item.name}</li>
{/each}

{#await fetchData()}
  <p>Loading...</p>
{:then data}
  <p>{data.name}</p>
{:catch error}
  <p>Error: {error.message}</p>
{/await}
$bindable — two-way binding components
<!-- TextInput.svelte -->
<script>
  let { value = $bindable('') } = $props();
</script>
<input bind:value />

<!-- Usage -->
<script>
  let name = $state('');
</script>
<TextInput bind:value={name} />

🎨 Styling

Scoped styles and :global css
<!-- Styles are scoped to this component by default -->
<style>
  p { color: blue; }           /* Only affects <p> in this component */
  :global(body) { margin: 0; } /* Affects global body */
</style>

<!-- Conditional classes -->
<div class:active={isActive} class:highlight={score > 90}>
  Content
</div>

📡 Events & Bindings

Event handlers and bind: events
<script>
  let value = $state('');
</script>

<input bind:value />
<input oninput={(e) => value = e.target.value} />

<button onclick={() => console.log('clicked')}>Click</button>
<form onsubmit|preventDefault={handleSubmit}>...</form>

<!-- Bind to DOM properties -->
<div bind:clientWidth={width} bind:clientHeight={height} />
<video bind:currentTime bind:duration bind:paused />

🏪 Stores

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

export const count = writable(0);
export const time = readable(new Date(), (set) => {
  const interval = setInterval(() => set(new Date()), 1000);
  return () => clearInterval(interval);
});
export const doubled = derived(count, ($count) => $count * 2);
<script>
  import { count } from './stores.js';
</script>

<!-- Auto-subscribe with $ prefix -->
<p>{$count}</p>
<button onclick={() => $count++}>+1</button>

See also: What is Vite? | Tailwind CSS cheat sheet