Source profileQuality 91/100

agents-inc/skills/src/skills/web-framework-svelte/SKILL.md

web-framework-svelte

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

Source repository stars
23
Declared platforms
0
Static risk flags
1
Last source update
2026-08-09
Source checked
2026-08-28

Decision brief

What it does: where it fits

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.

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/agents-inc/skills --skill "src/skills/web-framework-svelte"
    Safe inspection promptEditorial

    Inspect the Agent Skill "web-framework-svelte" from https://github.com/agents-inc/skills/blob/81d43a51211aca12c85dcc16085fa99014ec548e/src/skills/web-framework-svelte/SKILL.md at commit 81d43a51211aca12c85dcc16085fa99014ec548e. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      CRITICAL: Before Using This Skill

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

      Building Svelte 5 components with Runes reactivityManaging component state with $state and computed values with $derivedCreating reusable markup with snippets (replacing slots)
    2. 02

      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.

      Explicit reactivity — Runes ($state, $derived, $effect) make reactive declarations visible. No hidden compiler transformations.Derived over effects — Compute values with $derived, not $effect. Effects are escape hatches, not primary tools.Deep reactivity by default — $state creates deeply reactive proxies for objects/arrays. Mutations are tracked automatically.
    3. 03

      Core Patterns

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

      Use $state to declare reactive variables. Updates to $state variables automatically trigger UI re-renders.Why good: Explicit reactive declaration, named constants for magic numbers, plain function event handlersWhy bad: $: is Svelte 4 syntax deprecated in Svelte 5, implicit reactivity is confusing and non-portable
    4. 04

      Pattern 1: Reactive State with $state

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

      Use $state to declare reactive variables. Updates to $state variables automatically trigger UI re-renders.Why good: Explicit reactive declaration, named constants for magic numbers, plain function event handlersWhy bad: $: is Svelte 4 syntax deprecated in Svelte 5, implicit reactivity is confusing and non-portable
    5. 05

      Deep Reactivity

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

      $state creates deep proxies for objects and arrays — mutations are tracked automatically:Why good: No need for immutable update patterns, array methods like .push() trigger reactivity, property mutations tracked deeply

    Permission review

    Static risk signals and limitations

    Network access

    medium · line 327

    The documentation includes network, browsing, or remote request actions.

    const response = await fetch(`/api/search?q=${encodeURIComponent(query)}`);

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score91/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars23SourceRepository attention, not individual Skill quality
    Compatibility0 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    agents-inc/skills
    Skill path
    src/skills/web-framework-svelte/SKILL.md
    Commit
    81d43a51211aca12c85dcc16085fa99014ec548e
    License
    MIT
    Collected
    2026-08-28
    Default branch
    main
    View the original SKILL.md

    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

    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

    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


    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+)

    <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>

    Frequently asked questions

    What to verify before installation and use

    What does the web-framework-svelte source document cover?

    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.

    How do I install web-framework-svelte?

    The source record exposes this install command: npx skills add https://github.com/agents-inc/skills --skill "src/skills/web-framework-svelte". Inspect the command and pinned source before running it.

    Which permission-related actions were detected?

    Static rules flagged network in the source; the page lists the matching lines and excerpts.

    Alternatives

    Compare before choosing

    Computed 10045,960

    coreyhaines31/marketingskills

    ab-testing

    When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program

    Computed 10029,236

    garrytan/gbrain

    bulk-ingestion

    End-to-end discipline for turning any large data source (audio libraries, email takeouts, document corpora, chat exports, API dumps) into brain pages at scale. The lifecycle spine: SCHEMA → ACCESS → TRIAL → EVALUATE → IMPROVE → CODIFY → TEST → SKILLIFY → BULK → MONITOR. State is tracked in a durable JSON manifest (see MANIFEST-PATTERN.md) so any crash, session boundary, or subagent fan-out resumes from ground truth instead of memory.

    Computed 10025,136

    alirezarezvani/claude-skills

    app-store-optimization

    App Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklist

    Computed 1005,277

    dotnet/skills

    migrate-vstest-to-mtp

    Migrates .NET test projects from VSTest to Microsoft.Testing.Platform (MTP). Use when user asks to "migrate to MTP", "switch from VSTest", "enable Microsoft.Testing.Platform", "use MTP runner", set OutputType=Exe only for test projects in Directory.Build.props, or mentions EnableMSTestRunner, EnableNUnitRunner, or UseMicrosoftTestingPlatformRunner. USE FOR: MTP behavioral differences vs VSTest (exit code 8, zero tests discovered, --ignore-exit-code, TESTINGPLATFORM_EXITCODE_IGNORE); centralizing