jpskill.com
🛠️ 開発・MCP コミュニティ

web-framework-svelte

Svelte 5のRunesという新しい仕組みを使って、状態管理やデータの加工、イベント処理などを効率的に行い、より使いやすいウェブサイトやアプリケーションを開発するSkill。

📜 元の英語説明(参考)

Svelte 5 Runes reactivity - $state, $derived, $effect, $props, $bindable, components, snippets, event handling, context API

🇯🇵 日本人クリエイター向け解説

一言でいうと

Svelte 5のRunesという新しい仕組みを使って、状態管理やデータの加工、イベント処理などを効率的に行い、より使いやすいウェブサイトやアプリケーションを開発するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o web-framework-svelte.zip https://jpskill.com/download/10285.zip && unzip -o web-framework-svelte.zip && rm web-framework-svelte.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/10285.zip -OutFile "$d\web-framework-svelte.zip"; Expand-Archive "$d\web-framework-svelte.zip" -DestinationPath $d -Force; ri "$d\web-framework-svelte.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して web-framework-svelte.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → web-framework-svelte フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

Svelte 5 のパターン

クイックガイド: Svelte 5 では、明示的なリアクティビティのために Runes を使用します。リアクティブな変数には $state、計算された値には $derived、エスケープハッチとしてのみ $effect を使用します。スロットの代わりにスニペットを使用します。イベントディスパッチャーの代わりにコールバックプロップを使用します。コンポーネントを小さく、構成可能に保ちます。


<critical_requirements>

重要: この Skill を使用する前に

すべてのコードは、CLAUDE.md のプロジェクト規約に従う必要があります (kebab-case、名前付きエクスポート、インポート順序、import type、名前付き定数)

(Svelte 5 の Runes 構文を使用する必要があります — export let$:, ストアのような Svelte 4 のパターンは使用しないでください)

(計算された値には $derived を使用する必要があります — 状態を同期するために $effect を使用しないでください)

(スロット (<slot>) の代わりにスニペット ({#snippet} / {@render}) を使用する必要があります)

(createEventDispatcher の代わりにコールバックプロップ (onclick, onsomething) を使用する必要があります)

(変更ではなく置き換えられる大きなオブジェクト/配列には $state.raw() を使用する必要があります)

(生の setContext/getContext と文字列キーの代わりに、型安全なコンテキストには createContext を使用する必要があります)

</critical_requirements>


自動検出: Svelte 5, Runes, $state, $derived, $effect, $props, $bindable, $inspect, .svelte, snippet, @render, createContext, getContext, setContext, $state.raw, $state.eager, $derived.by, $effect.pre, ClassValue

いつ使用するか:

  • Runes リアクティビティを使用して Svelte 5 コンポーネントを構築する場合
  • $state でコンポーネントの状態を管理し、$derived で計算された値を管理する場合
  • スニペット (スロットの代替) で再利用可能なマークアップを作成する場合
  • ネイティブのイベント属性とコールバックプロップでイベントを処理する場合
  • コンテキスト API でコンポーネント間で状態を共有する場合
  • $bindable プロップで双方向バインディングを行う場合

カバーする主なパターン:

  • Runes: $state, $derived, $effect, $props, $bindable, $inspect
  • スニペットと {@render} を使用したコンポーネント構成
  • ネイティブ属性とコールバックプロップを使用したイベント処理
  • 型安全なコンポーネント間状態のための createContext を使用したコンテキスト API
  • $state フィールドを使用したクラスベースのリアクティブな状態
  • 深いリアクティビティと浅いリアクティビティ ($state$state.raw)

いつ使用しないか:

  • メタフレームワーク固有のパターン (ルーティング、ロード関数、フォームアクション) — 対応するメタフレームワークの Skill を使用してください
  • Svelte 4 のパターン (export let, $:, リアクティブステートメント, <slot>, createEventDispatcher)
  • サーバーサイドロジック (メタフレームワークのサーバーフックとルートを使用してください)

詳細なリソース:

  • 意思決定フレームワークとアンチパターンについては、reference.md を参照してください

Runes とリアクティビティ:

  • examples/core.md - $state, $derived, $effect, $props, $bindable, コンポーネントパターン

コンポーネントパターン:

  • examples/snippets.md - スニペットブロック, {@render}, スニペットをプロップとして渡す, スロットの置き換え
  • examples/events.md - イベント処理, コールバックプロップによるコンポーネントイベント, イベント修飾子

高度な内容:

  • examples/advanced.md - $inspect, コンテキスト API, $state.raw, $state.eager, クラスベースの状態, 共有状態モジュール

<philosophy>

Philosophy

Svelte 5 では、Svelte に明示的できめ細かいリアクティビティをもたらす一連のプリミティブである Runes が導入されました。Svelte 4 のコンパイラマジック ($:, export let) とは異なり、Runes はリアクティビティを .svelte ファイル、.ts ファイル、およびクラス定義全体で可視化し、移植可能にします。

コア原則:

  1. 明示的なリアクティビティ — Runes ($state, $derived, $effect) は、リアクティブな宣言を可視化します。隠れたコンパイラ変換はありません。
  2. エフェクトよりも派生$effect ではなく $derived で値を計算します。エフェクトはエスケープハッチであり、主要なツールではありません。
  3. デフォルトで深いリアクティビティ$state は、オブジェクト/配列に対して深いリアクティブプロキシを作成します。変更は自動的に追跡されます。
  4. スニペットはスロットを置き換える{#snippet} ブロックは、<slot> 要素よりも強力で、型付けされ、構成可能です。
  5. コールバックプロップはイベントディスパッチャーを置き換えるcreateEventDispatcher を使用する代わりに、onsomething コールバックプロップを渡します。
  6. コンパイル時の最適化 — Svelte はコンポーネントを効率的な命令型コードにコンパイルします。実行時に仮想 DOM の差分処理は行いません。

Svelte 5 Runes をいつ使用するか:

  • すべての新しい Svelte コンポーネント (Runes は Svelte 5 のデフォルトです)
  • .svelte.ts または .svelte.js ファイル内のリアクティブな状態
  • リアクティブなフィールドを持つクラスベースの状態
  • リアクティブな状態に依存する計算された値

いつ使用しないか:

  • 非リアクティブな定数 (プレーンな const または let を使用)
  • リアクティビティを必要としないサーバーサイドコード
  • メタフレームワークの懸念事項 (ルーティング、ロード関数、サーバーフック) — 対応するメタフレームワークの Skill を使用してください
  • Svelte 4 のパターン — export let, $:, コンポーネントの状態のためのストア, <slot>, createEventDispatcher

</philosophy>


<patterns>

コアパターン

パターン 1: $state を使用したリアクティブな状態

$state を使用してリアクティブな変数を宣言します。$state 変数への更新は、UI の再レンダリングを自動的にトリガーします。

<!-- counter.svelte -->
<script lang="ts">
  let count = $state(0);
  const STEP = 5;

  function increment() {
    count += 1;
  }

  function incrementByStep() {
    count += STEP;
  }
</script>

<button onclick={increment}>
  Count: {count}
</button>
<button onclick={incrementByStep}>
  +{STEP}
</button>

良い理由: 明示的なリアクティブ宣言、マジックナンバーの名前付き定数、プレーンな関数イベントハンドラー

<!-- 悪い例: Svelte 4 スタイル -->
<script>
  let count = 0; // Svelte 5 モードでは明示的にリアクティブではありません
  $: doubled = count * 2; // Svelte 4 のリアクティブステートメント
</script>

悪い理由: $ は Svelte 5 で非推奨の Svelte 4 構文であり、暗黙的なリアクティビティは紛らわしく、移植できません

深いリアクティビティ

$state はオブジェクトと配列に対して深いプロキシを作成します — 変更は自動的に追跡されます:


<script lang="ts">
  interface Todo {
    done: boolean;
    text: string;
  }

  let todos = $state<Todo[]>([
    { done: false, text: 'Learn Svelte 5'

(原文がここで切り詰められています)
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Svelte 5 Patterns

Quick Guide: Svelte 5 uses Runes for explicit reactivity. Use $state for reactive variables, $derived for computed values, $effect only as an escape hatch. Use snippets instead of slots. Use callback props instead of event dispatchers. Keep components small and composable.


<critical_requirements>

CRITICAL: Before Using This Skill

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

(You MUST use Svelte 5 Runes syntax — NOT Svelte 4 patterns like export let, $:, or stores for component state)

(You MUST use $derived for computed values — NEVER use $effect to synchronize state)

(You MUST use snippets ({#snippet} / {@render}) instead of slots (<slot>))

(You MUST use callback props (onclick, onsomething) instead of createEventDispatcher)

(You MUST use $state.raw() for large objects/arrays that are replaced, not mutated)

(You MUST use createContext for type-safe context instead of raw setContext/getContext with string keys)

</critical_requirements>


Auto-detection: Svelte 5, Runes, $state, $derived, $effect, $props, $bindable, $inspect, .svelte, snippet, @render, createContext, getContext, setContext, $state.raw, $state.eager, $derived.by, $effect.pre, ClassValue

When to use:

  • Building Svelte 5 components with Runes reactivity
  • Managing component state with $state and computed values with $derived
  • Creating reusable markup with snippets (replacing slots)
  • Handling events with native event attributes and callback props
  • Sharing state across components with context API
  • Two-way binding with $bindable props

Key patterns covered:

  • Runes: $state, $derived, $effect, $props, $bindable, $inspect
  • Component composition with snippets and {@render}
  • Event handling with native attributes and callback props
  • Context API with createContext for type-safe cross-component state
  • Class-based reactive state with $state fields
  • Deep vs shallow reactivity ($state vs $state.raw)

When NOT to use:

  • Meta-framework-specific patterns (routing, load functions, form actions) — use the corresponding meta-framework skill
  • Svelte 4 patterns (export let, $: reactive statements, <slot>, createEventDispatcher)
  • Server-side logic (use your meta-framework's server hooks and routes)

Detailed Resources:

  • For decision frameworks and anti-patterns, see reference.md

Runes & Reactivity:

  • examples/core.md - $state, $derived, $effect, $props, $bindable, component patterns

Component Patterns:

Advanced:

  • examples/advanced.md - $inspect, context API, $state.raw, $state.eager, class-based state, shared state modules

<philosophy>

Philosophy

Svelte 5 introduces Runes — a set of primitives that bring explicit, fine-grained reactivity to Svelte. Unlike Svelte 4's compiler magic ($:, export let), Runes make reactivity visible and portable across .svelte files, .ts files, and class definitions.

Core principles:

  1. Explicit reactivity — Runes ($state, $derived, $effect) make reactive declarations visible. No hidden compiler transformations.
  2. Derived over effects — Compute values with $derived, not $effect. Effects are escape hatches, not primary tools.
  3. Deep reactivity by default$state creates deeply reactive proxies for objects/arrays. Mutations are tracked automatically.
  4. Snippets replace slots{#snippet} blocks are more powerful, typed, and composable than <slot> elements.
  5. Callback props replace event dispatchers — Pass onsomething callback props instead of using createEventDispatcher.
  6. Compile-time optimization — Svelte compiles components to efficient imperative code. No virtual DOM diffing at runtime.

When to use Svelte 5 Runes:

  • All new Svelte components (Runes are the default in Svelte 5)
  • Reactive state in .svelte.ts or .svelte.js files
  • Class-based state with reactive fields
  • Any computed value that depends on reactive state

When NOT to use:

  • Non-reactive constants (use plain const or let)
  • Server-side code that doesn't need reactivity
  • Meta-framework concerns (routing, load functions, server hooks) — use the corresponding meta-framework skill
  • Svelte 4 patterns — export let, $:, stores for component state, <slot>, createEventDispatcher

</philosophy>


<patterns>

Core Patterns

Pattern 1: Reactive State with $state

Use $state to declare reactive variables. Updates to $state variables automatically trigger UI re-renders.

<!-- counter.svelte -->
<script lang="ts">
  let count = $state(0);
  const STEP = 5;

  function increment() {
    count += 1;
  }

  function incrementByStep() {
    count += STEP;
  }
</script>

<button onclick={increment}>
  Count: {count}
</button>
<button onclick={incrementByStep}>
  +{STEP}
</button>

Why good: Explicit reactive declaration, named constants for magic numbers, plain function event handlers

<!-- BAD: Svelte 4 style -->
<script>
  let count = 0; // Not explicitly reactive in Svelte 5 mode
  $: doubled = count * 2; // Svelte 4 reactive statement
</script>

Why bad: $: is Svelte 4 syntax deprecated in Svelte 5, implicit reactivity is confusing and non-portable

Deep Reactivity

$state creates deep proxies for objects and arrays — mutations are tracked automatically:

<script lang="ts">
  interface Todo {
    done: boolean;
    text: string;
  }

  let todos = $state<Todo[]>([
    { done: false, text: 'Learn Svelte 5' }
  ]);

  function addTodo(text: string) {
    todos.push({ done: false, text }); // Mutation tracked!
  }

  function toggleTodo(index: number) {
    todos[index].done = !todos[index].done; // Deep mutation tracked!
  }
</script>

Why good: No need for immutable update patterns, array methods like .push() trigger reactivity, property mutations tracked deeply


Pattern 2: Computed Values with $derived

Use $derived for values that depend on other reactive state. Never use $effect to synchronize state.

<script lang="ts">
  let count = $state(0);

  // Simple expression
  let doubled = $derived(count * 2);

  // Complex computation with $derived.by
  let stats = $derived.by(() => {
    const isEven = count % 2 === 0;
    const isPositive = count > 0;
    return { isEven, isPositive };
  });
</script>

<p>{count} doubled is {doubled}</p>
<p>Even: {stats.isEven}, Positive: {stats.isPositive}</p>

Why good: Automatically recalculates when dependencies change, no side effects, push-pull reactivity avoids unnecessary recalculations

<!-- BAD: Using $effect to synchronize state -->
<script lang="ts">
  let count = $state(0);
  let doubled = $state(0);

  $effect(() => {
    doubled = count * 2; // WRONG: Use $derived instead
  });
</script>

Why bad: $effect for derived state creates unnecessary reactive subscriptions, runs after DOM update (timing issues), harder to reason about data flow


Pattern 3: Component Props with $props

Use $props to declare component inputs. Supports destructuring, defaults, rest props, and TypeScript.

<!-- user-card.svelte -->
<script lang="ts">
  interface Props {
    name: string;
    email: string;
    role?: string;
    class?: string;
  }

  let { name, email, role = 'member', ...rest }: Props = $props();

  // Derived from props — updates when props change
  let initials = $derived(
    name.split(' ').map(n => n[0]).join('').toUpperCase()
  );
</script>

<div class="user-card" {...rest}>
  <span class="avatar">{initials}</span>
  <h3>{name}</h3>
  <p>{email}</p>
  <span class="badge">{role}</span>
</div>

Why good: Type-safe props with interface, destructuring with defaults, rest props for pass-through, derived values update with prop changes

<!-- BAD: Svelte 4 style -->
<script>
  export let name; // Svelte 4 prop declaration
  export let email;
  export let role = 'member';
</script>

Why bad: export let is Svelte 4 syntax deprecated in Svelte 5, no type safety, no rest props


Pattern 4: Two-Way Binding with $bindable

Use $bindable to declare props that support two-way binding with bind:. Use sparingly — prefer one-way data flow.

<!-- text-input.svelte -->
<script lang="ts">
  interface Props {
    value: string;
    placeholder?: string;
  }

  let { value = $bindable(''), placeholder = '' }: Props = $props();
</script>

<input
  bind:value={value}
  {placeholder}
  class="text-input"
/>
<!-- parent.svelte -->
<script lang="ts">
  import TextInput from './text-input.svelte';

  let searchQuery = $state('');
</script>

<TextInput bind:value={searchQuery} placeholder="Search..." />
<p>Searching for: {searchQuery}</p>

Why good: Explicit two-way binding declaration, parent controls the state, child can modify via bind:, TypeScript-safe

When to use: Form inputs, UI primitives (sliders, toggles) where two-way binding simplifies the API

When not to use: Most component communication — prefer callback props for explicit data flow


Pattern 5: Side Effects with $effect

Use $effect for side effects that need to run when reactive state changes. This is an escape hatch — prefer $derived for computed values and event handlers for user-triggered actions.

<script lang="ts">
  let searchQuery = $state('');
  let results = $state<string[]>([]);
  const DEBOUNCE_MS = 300;

  // Good: Side effect for external API calls
  $effect(() => {
    const query = searchQuery;

    if (!query) {
      results = [];
      return;
    }

    const timer = setTimeout(async () => {
      const response = await fetch(`/api/search?q=${encodeURIComponent(query)}`);
      results = await response.json();
    }, DEBOUNCE_MS);

    // Cleanup function runs before next effect and on unmount
    return () => clearTimeout(timer);
  });
</script>

<input bind:value={searchQuery} placeholder="Search..." />

{#each results as result}
  <p>{result}</p>
{/each}

Why good: External API call is a legitimate side effect, cleanup prevents stale requests, named constant for debounce

When NOT to Use $effect

<script lang="ts">
  let count = $state(0);

  // BAD: Synchronizing state — use $derived
  // $effect(() => { doubled = count * 2; });

  // BAD: Logging in effect — use $inspect for debugging
  // $effect(() => { console.log(count); });

  // BAD: Calling functions on change — use event handlers
  // $effect(() => { if (count > 10) showAlert(); });

  // GOOD: Use $derived for computed values
  let doubled = $derived(count * 2);
</script>

Pattern 6: Snippets (Replacing Slots)

Snippets are reusable markup blocks declared with {#snippet} and rendered with {@render}. They replace Svelte 4's <slot> elements.

<!-- card.svelte -->
<script lang="ts">
  import type { Snippet } from 'svelte';

  interface Props {
    title: string;
    children: Snippet;
    footer?: Snippet;
  }

  let { title, children, footer }: Props = $props();
</script>

<div class="card">
  <h2>{title}</h2>
  <div class="card-body">
    {@render children()}
  </div>
  {#if footer}
    <div class="card-footer">
      {@render footer()}
    </div>
  {/if}
</div>
<!-- usage -->
<script lang="ts">
  import Card from './card.svelte';
</script>

<Card title="Welcome">
  <p>This becomes the children snippet automatically.</p>

  {#snippet footer()}
    <button>Learn More</button>
  {/snippet}
</Card>

Why good: Type-safe with Snippet type, optional snippets with conditional rendering, children is implicit for content between tags

<!-- BAD: Svelte 4 slots -->
<div class="card">
  <slot /> <!-- Deprecated in Svelte 5 -->
  <slot name="footer" /> <!-- Use snippets instead -->
</div>

Why bad: <slot> is deprecated in Svelte 5, no type safety, less composable than snippets


Pattern 7: Event Handling

Svelte 5 uses native event attributes (onclick, onsubmit) instead of Svelte 4's on:click directive. Component events use callback props.

Element Events

<script lang="ts">
  let count = $state(0);

  function handleClick(event: MouseEvent) {
    count += 1;
  }

  function handleSubmit(event: SubmitEvent) {
    event.preventDefault();
    // handle form
  }
</script>

<button onclick={handleClick}>Clicked {count} times</button>

<!-- Inline handlers are fine for simple logic -->
<button onclick={() => count = 0}>Reset</button>

<form onsubmit={handleSubmit}>
  <input name="query" />
  <button type="submit">Search</button>
</form>

Component Events via Callback Props

<!-- color-picker.svelte -->
<script lang="ts">
  interface Props {
    color: string;
    onchange?: (color: string) => void;
    onreset?: () => void;
  }

  let { color, onchange, onreset }: Props = $props();

  const COLORS = ['red', 'green', 'blue', 'purple'] as const;
</script>

{#each COLORS as c}
  <button
    onclick={() => onchange?.(c)}
    class={{ selected: color === c }}
  >
    {c}
  </button>
{/each}

{#if onreset}
  <button onclick={onreset}>Reset</button>
{/if}
<!-- parent.svelte -->
<script lang="ts">
  import ColorPicker from './color-picker.svelte';

  let selectedColor = $state('red');
</script>

<ColorPicker
  color={selectedColor}
  onchange={(c) => selectedColor = c}
  onreset={() => selectedColor = 'red'}
/>

Why good: Type-safe callback props, optional with ?. call, parent controls event handling, no indirection through dispatcher

<!-- BAD: Svelte 4 event dispatcher -->
<script>
  import { createEventDispatcher } from 'svelte';
  const dispatch = createEventDispatcher();

  function handleClick() {
    dispatch('change', { color: 'red' }); // Deprecated pattern
  }
</script>

Why bad: createEventDispatcher is deprecated in Svelte 5, no type safety, requires manual event typing

</patterns>


<integration>

Integration Guide

Styling integration:

  • Scoped <style> blocks are the default — styles don't leak to other components
  • Use :global() for global styles or CSS custom properties for parent-to-child styling
  • Any CSS approach (CSS Modules, utility-first, preprocessors) works with Svelte

State management:

  • $state for component-local state
  • Context API (createContext) for subtree-scoped state
  • Reactive classes with $state fields for shared state modules (.svelte.ts)
  • Meta-framework load functions for server state

TypeScript integration:

  • Full TypeScript support in <script lang="ts"> blocks
  • Snippet<[ParamType]> for typed snippet props
  • Interface-based prop typing with $props()
  • ClassValue type from svelte/elements for type-safe class props (Svelte 5.19+)

</integration>


<red_flags>

RED FLAGS

High Priority:

  • Using export let for props — use $props() instead
  • Using $: reactive statements — use $derived or $effect
  • Using <slot> or <slot name="x"> — use {#snippet} and {@render}
  • Using createEventDispatcher — use callback props
  • Using $effect to sync state — use $derived for computed values
  • Destructuring $state objects — breaks reactivity (values captured at destructure time)

Medium Priority:

  • Using on:click directive — use onclick attribute
  • Not using $state.raw() for large API responses — unnecessary proxy overhead
  • Using setContext/getContext with string keys — use createContext for type safety
  • Using class:name={condition} — use built-in class attribute object/array syntax (since 5.16)

Gotchas:

  • $state proxies are not the original object — use $state.snapshot() to get a plain copy
  • Destructuring $state captures values, not references — access properties directly instead
  • $derived return values are NOT deeply reactive — only $state creates deep proxies
  • $effect runs after DOM update — use $effect.pre() for pre-update timing
  • Dependencies after await in $effect are not tracked
  • Context must be set during component init — cannot call setContext in event handlers or $effect

For complete decision frameworks and the full anti-patterns list, see reference.md.

</red_flags>


<critical_reminders>

CRITICAL REMINDERS

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

(You MUST use Svelte 5 Runes syntax — NOT Svelte 4 patterns like export let, $:, or stores for component state)

(You MUST use $derived for computed values — NEVER use $effect to synchronize state)

(You MUST use snippets ({#snippet} / {@render}) instead of slots (<slot>))

(You MUST use callback props (onclick, onsomething) instead of createEventDispatcher)

(You MUST use $state.raw() for large objects/arrays that are replaced, not mutated)

(You MUST use createContext for type-safe context instead of raw setContext/getContext with string keys)

Failure to follow these rules will produce outdated Svelte 4 code that is deprecated and will break in future versions.

</critical_reminders>