Skip to main content
Svelte Fundamentals
CHAPTER 27 Beginner

Advanced Svelte Concepts

Updated: May 18, 2026
5 min read

# CHAPTER 27

Advanced Svelte Concepts

1. Chapter Introduction

This chapter explores the advanced features that senior Svelte developers use daily: custom actions for reusable DOM behaviors, Svelte 5's Runes for next-generation reactivity, crossfade for shared element transitions, and SSR hydration concepts.

2. Learning Objectives

  • Create custom Svelte actions (use:).
  • Implement advanced transition patterns with crossfade.
  • Understand Svelte 5 Runes ($state, $derived, $effect).
  • Understand SSR hydration.
  • Build a custom localStorage store.

3. Custom Actions (use:)

Actions are functions that run when an element is mounted/destroyed. They encapsulate reusable DOM behaviors:
javascript
12345678910111213141516
// src/lib/actions/clickOutside.js
export function clickOutside(node, callback) {
  function handleClick(event) {
    if (!node.contains(event.target)) {
      callback();
    }
  }

  document.addEventListener('click', handleClick, true);

  return {
    destroy() {
      document.removeEventListener('click', handleClick, true);
    }
  };
}
javascript
12345678910111213141516171819202122
// src/lib/actions/tooltip.js
export function tooltip(node, text) {
  const tip = document.createElement('div');
  tip.className = 'tooltip';
  tip.textContent = text;

  node.addEventListener('mouseenter', () => {
    document.body.appendChild(tip);
    const rect = node.getBoundingClientRect();
    tip.style.cssText = `position:fixed;top:${rect.top - 36}px;left:${rect.left}px;
      background:#1e293b;color:white;padding:4px 8px;border-radius:6px;font-size:12px;z-index:9999`;
  });

  node.addEventListener('mouseleave', () => {
    tip.remove();
  });

  return {
    update(newText) { tip.textContent = newText; },
    destroy() { tip.remove(); }
  };
}
svelte
12345678910111213
<!-- Using actions -->
<script>
  import { clickOutside } from &#039;$lib/actions/clickOutside.js';
  import { tooltip } from &#039;$lib/actions/tooltip.js';
  let open = false;
</script>

<div use:clickOutside={() => open = false}>
  <button on:click={() => open = !open}>Toggle Menu</button>
  {#if open}<div class="menu">Menu items...</div>{/if}
</div>

<button use:tooltip={&#039;Click to save'} on:click={save}>💾</button>

4. crossfade — Shared Element Transitions

svelte
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
<script>
  import { crossfade } from &#039;svelte/transition';
  import { quintOut } from &#039;svelte/easing';

  const [send, receive] = crossfade({
    duration: 400,
    easing: quintOut,
    fallback: (node) => ({ duration: 200, css: t => `opacity: ${t}` })
  });

  let todo = [
    { id: 1, done: false, text: &#039;Learn Svelte' },
    { id: 2, done: false, text: &#039;Build something' }
  ];

  $: active = todo.filter(t => !t.done);
  $: done = todo.filter(t => t.done);

  function mark(item, isDone) {
    todo = todo.map(t => t.id === item.id ? { ...t, done: isDone } : t);
  }
</script>

<div class="columns">
  <div class="column">
    <h2>Active</h2>
    {#each active as item (item.id)}
      <div
        class="item"
        in:receive={{ key: item.id }}
        out:send={{ key: item.id }}
      >
        {item.text}
        <button on:click={() => mark(item, true)}>✓</button>
      </div>
    {/each}
  </div>

  <div class="column">
    <h2>Done</h2>
    {#each done as item (item.id)}
      <div
        class="item done"
        in:receive={{ key: item.id }}
        out:send={{ key: item.id }}
      >
        {item.text}
        <button on:click={() => mark(item, false)}>↩</button>
      </div>
    {/each}
  </div>
</div>

5. Custom localStorage Store

javascript
12345678910111213141516171819
// src/lib/stores/persistent.js
import { writable } from &#039;svelte/store&#039;;

export function persistent(key, defaultValue) {
  const stored = typeof localStorage !== &#039;undefined&#039;
    ? localStorage.getItem(key)
    : null;

  const initial = stored !== null ? JSON.parse(stored) : defaultValue;
  const store = writable(initial);

  store.subscribe(value => {
    if (typeof localStorage !== &#039;undefined&#039;) {
      localStorage.setItem(key, JSON.stringify(value));
    }
  });

  return store;
}
svelte
12345
<script>
  import { persistent } from &#039;$lib/stores/persistent.js';
  const theme = persistent(&#039;theme', 'light');
</script>
<!-- theme persists across page refreshes! -->

6. Svelte 5 Runes (Future-Proof)

Svelte 5 introduces Runes — new syntax for more explicit reactivity:
svelte
1234567891011121314
<!-- Svelte 5 -->
<script>
  let count = $state(0);               // Replaces: let count = 0;
  let doubled = $derived(count * 2);   // Replaces: $: doubled = count * 2;

  $effect(() => {                       // Replaces: reactive block
    console.log(&#039;Count changed:', count);
    return () => console.log(&#039;cleanup');
  });
</script>

<button onclick={() => count++}>
  Count: {count} (Doubled: {doubled})
</button>

7. SSR and Hydration Concepts

text
12345678910
SSR Flow in SvelteKit:
1. User requests /products
2. Server runs load() function — fetches data from DB
3. Server renders HTML with data embedded
4. Browser receives complete HTML → FAST first paint
5. Svelte JS hydrates — attaches event listeners to server-rendered HTML
6. App is now interactive (CSR takes over)

Hydration: The process of Svelte attaching its reactivity system
to HTML that was pre-rendered on the server.

8. MCQs

Question 1

What is a Svelte action?

Question 2

What does an action's destroy function do?

Question 3

What is crossfade used for?

Question 4

What Svelte 5 rune replaces let count = 0 for reactive state?

Question 5

What Svelte 5 rune replaces $: derived = value * 2?

Question 6

What is SSR hydration?

Question 7

What is the benefit of SSR for SEO?

Question 8

What does action.update(newParams) do?

Question 9

What Svelte 5 rune replaces $: side-effect blocks?

Question 10

What is a persistent store?

9. Interview Questions

  • Q: Implement a clickOutside Svelte action from scratch.
  • Q: What is SSR hydration and why does it matter for performance?

10. Summary

Custom actions, crossfade transitions, persistent stores, and Svelte 5 Runes represent the frontier of Svelte development. These advanced concepts separate engineers who know Svelte's API from engineers who understand Svelte's philosophy — leveraging the compiler to write the minimum possible code for maximum effect.

11. Next Chapter Recommendation

In Chapter 28: Svelte Data Structures and Algorithms UI, we build visual representations of common data structures — stacks, queues, and sorting algorithms — using Svelte's animations.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·