Skip to content
Development
Skill

/web-framework-svelte

Svelte 5 runes — $state, $derived, $effect, $props, $bindable, snippets, callback props, context. Load when writing Svelte 5 components or reactive modules.

From plugin
agents-inc-skills
24200 skills
Install
$ npx -y skills add agents-inc/skills --skill web-framework-svelte --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/web-framework-svelte

Context preview

The summary Claude sees to decide when to auto-load this skill.

Svelte 5 runes — $state, $derived, $effect, $props, $bindable, snippets, callback props, context. Load when writing Svelte 5 components or reactive modules.

SKILL.md

web-framework-svelte.SKILL.md
name: web-framework-svelte
description: Svelte 5 runes — $state, $derived, $effect, $props, $bindable, snippets, callback props, context. Load when writing Svelte 5 components or reactive modules.

Svelte 5 Patterns

> **Quick Guide:** Runes make reactivity explicit and portable out of `.svelte` files. `$state` for values that change, `$derived` for everything computed from them, `$effect` only for reaching outside the component. Snippets replace slots, callback props replace `createEventDispatcher`, and `onclick` replaces `on:click`. The Svelte 4 forms still compile, so nothing flags them.

**Detailed Resources:**

  • [examples/core.md](examples/core.md) — `$state`, `$state.raw`, `$derived`, `$props`, `$bindable`, `$effect`, `$effect.pre`
  • [examples/snippets.md](examples/snippets.md) — children, named snippets as props, parameters, optional and recursive snippets
  • [examples/events.md](examples/events.md) — element events, callback props, forwarding, window events, composing handlers
  • [examples/advanced.md](examples/advanced.md) — `$inspect`, context, shared state modules, class-based state, `$state.snapshot`, `$state.eager`
  • [reference.md](reference.md) — rune cheat sheet, Svelte 4 → 5 migration table, decision trees, component template

---

Which path applies

  • **Inside a `.svelte` component** — every rune is available, props arrive through `$props()`, and teardown belongs in the function an `$effect` returns.
  • **Inside a `.svelte.ts` or `.svelte.js` module** — `$state` and `$derived` work, but a reassigned export does not propagate to importers, because the binding is copied at import. Export an object or a class holding `$state` fields instead: [examples/advanced.md](examples/advanced.md).

---

<critical_requirements>

Before writing Svelte code

**Declare changing values with `$state` and compute from them with `$derived`.** A `$derived` recomputes lazily and cannot fall out of step; the same value maintained by an `$effect` updates after the DOM has already painted the old one.

**Pass composable markup as snippets — `{#snippet}` declares it, `{@render}` renders it.** Snippets are typed, take parameters, and can be passed as props; `<slot>` did none of that.

**Let a child notify its parent through a callback prop — `onsave`, `onselect`.** The signature is checked at the call site, where a dispatched event's payload was not.

**Reach for `$state.raw()` when a value is replaced wholesale rather than mutated.** It skips the deep proxy, which is the whole cost on a large array that only ever gets reassigned.

**Reach for `createContext<T>()` over `setContext`/`getContext`.** It hands back a typed `[get, set]` pair with the key minted for you, so no consumer casts and no two libraries collide on a string key — [examples/advanced.md](examples/advanced.md) has it.

</critical_requirements>

---

**Auto-detection:** Svelte 5, runes, $state, $derived, $effect, $props, $bindable, $inspect, .svelte, .svelte.ts, {#snippet}, {@render}, Snippet, createContext, setContext, getContext, $state.raw, $state.snapshot, $state.eager, $derived.by, $effect.pre, ClassValue

**Applies to:**

  • Component state, derived values and side effects with runes
  • Props, defaults, rest props and two-way binding with `$bindable`
  • Composition with snippets, including snippets passed as props
  • Event handling and parent-child communication
  • Context, shared state modules and class-based reactive state

**Handled elsewhere:**

  • Styling — a `<style>` block is scoped by the compiler, and which CSS approach fills it is not settled here
  • Routing, server-side loading and form submission — a meta-framework's concern, whichever one is in use
  • Server-state caching and invalidation
  • Test doubles for the network

---

<philosophy>

Philosophy

Svelte 4 inferred reactivity from position: a `let` at the top level of a component was reactive, `$:` re-ran on assignment, and neither meant anything in a `.ts` file. Runes replace that with a marker on the value itself, so the same declaration behaves identically in a component, a module and a class field.

The ordering that follows is: `$derived` for anything computable, an event handler for anything a user triggers, and `$effect` only for what is genuinely outside the component — a canvas, a third-party widget, a subscription. An `$effect` that assigns to `$state` is a `$derived` written the long way round, and it runs after the DOM update rather than before it.

</philosophy>

---

<patterns>

Core patterns

Pattern 1: $state

`$state` makes a value reactive and, for objects and arrays, deeply so — `push` and property assignment are both tracked, with no immutable update dance.

<script lang="ts">
  let count = $state(0);
  let todos = $state<Todo[]>([]);

  function addTodo(text: string) {
    todos.push({ done: false, text });
  }
</script>

Full code: [examples/core.md](examples/core.md)

---

Pattern 2: $derived

`$derived` takes an expression, `$derived.by` a function for anything longer. Both recompute only when a dependency actually changed.

<script lang="ts">
  let doubled = $derived(count * 2);

  let stats = $derived.by(() => ({
    isEven: count % 2 === 0,
    isPositive: count > 0,
  }));
</script>

Full code: [examples/core.md](examples/core.md)

---

Pattern 3: $props

Props are destructured out of `$props()` with defaults and rest, and typed by an interface.

<script lang="ts">
  interface Props {
    name: string;
    role?: string;
    class?: string;
  }

  let { name, role = 'member', ...rest }: Props = $props();
  let initials = $derived(name.split(' ').map((n) => n[0]).join(''));
</script>

Destructuring `$props()` is the one place it is safe — the compiler keeps the bindings live. Destructuring a `$state` object does not.

Full code: [examples/core.md](examples/core.md)

---

Pattern 4: $bindable

`$bindable` marks a prop the child may write back through `bind:`. Worth it

Read more
Ships withagents-inc-skills

The official skills marketplace for Agents Inc. 150+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?

Get the whole plugin

Other skills on agents-inc-skills.