Created
March 6, 2026 14:16
-
-
Save nickludlam/919bdf0d5274ffbe65af5cb5f26d133f to your computer and use it in GitHub Desktop.
LLM written Agents.md for Svelte 5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Code Assistant Directives for Svelte 5 Runes | |
| This document directs code assistants to write code using **Svelte 5 Runes**, the new reactivity model in Svelte 5. | |
| ## Overview | |
| Svelte Runes are a set of powerful APIs that provide fine-grained reactivity in Svelte 5. When writing or modifying code in this project, always use runes instead of the legacy reactive declarations and statements. | |
| ## Core Runes | |
| ### 1. `$state` - Reactive State | |
| Use `$state` to declare reactive variables that automatically update the UI when changed. | |
| **Directive**: Always use `$state` instead of `let` for variables that should be reactive. | |
| ```svelte | |
| <script> | |
| let count = $state(0); | |
| let name = $state(''); | |
| let items = $state([]); | |
| </script> | |
| <button onclick={() => count++}> | |
| Count: {count} | |
| </button> | |
| ``` | |
| ### 2. `$derived` - Computed Values | |
| Use `$derived` for values that depend on other reactive states. They automatically update when dependencies change. | |
| **Directive**: Use `$derived` instead of reactive declarations (`$:`) for computed values. | |
| ```svelte | |
| <script> | |
| let count = $state(0); | |
| let doubled = $derived(count * 2); | |
| let message = $derived(`Count is ${count}`); | |
| </script> | |
| ``` | |
| ### 3. `$derived.by()` - Complex Computed Values | |
| Use `$derived.by()` for computed values that require more complex logic or multiple statements. | |
| **Directive**: Use `$derived.by()` when `$derived` expression becomes too complex or when you need procedural logic to compute the value. | |
| ```svelte | |
| <script> | |
| let count = $state(0); | |
| let multiplier = $state(2); | |
| let result = $derived.by(() => { | |
| if (count === 0) return 0; | |
| const base = count * multiplier; | |
| return base + 10; | |
| }); | |
| </script> | |
| <p>Result: {result}</p> | |
| ``` | |
| ### 4. `$effect` - Side Effects | |
| Use `$effect` to run code when dependencies change. This replaces lifecycle methods like `onMount` and reactive statements. | |
| **Directive**: Use `$effect` for setting up timers, API calls, subscriptions, and other side effects. | |
| ```svelte | |
| <script> | |
| import { onDestroy } from 'svelte'; | |
| let count = $state(0); | |
| $effect(() => { | |
| console.log('Count changed to:', count); | |
| document.title = `Count: ${count}`; | |
| // Cleanup function | |
| return () => { | |
| console.log('Cleaning up'); | |
| }; | |
| }); | |
| </script> | |
| ``` | |
| ### 5. `$effect.pre` - Pre-Effect | |
| Use `$effect.pre` for effects that should run before the DOM updates. | |
| ```svelte | |
| <script> | |
| let value = $state(''); | |
| $effect.pre(() => { | |
| console.log('This runs before DOM update:', value); | |
| }); | |
| </script> | |
| ``` | |
| ### 6. `$props` - Component Props | |
| Use `$props` to declare and destructure component properties. | |
| **Directive**: Always use `$props` instead of `export let` for component properties. | |
| ```svelte | |
| <script> | |
| interface Props { | |
| title: string; | |
| count?: number; | |
| onclick?: () => void; | |
| } | |
| const { title, count = 0, onclick } = $props(); | |
| </script> | |
| <button {onclick}> | |
| {title}: {count} | |
| </button> | |
| ``` | |
| ### 6. `$bindable` - Two-way Bindings | |
| Use `$bindable` for properties that should support two-way binding with `bind:`. | |
| ```svelte | |
| <script> | |
| let value = $state(''); | |
| </script> | |
| <Input bind:value /> | |
| ``` | |
| In a child component: | |
| ```svelte | |
| <script> | |
| const { value = $bindable('') } = $props(); | |
| </script> | |
| <input bind:value /> | |
| ``` | |
| ### 7. `$host` - Host Element | |
| Use `$host` to access the host element in custom elements or Web Components. | |
| ```svelte | |
| <script> | |
| let element = $host(); | |
| $effect(() => { | |
| element.classList.add('active'); | |
| }); | |
| </script> | |
| ``` | |
| ## Migration Guidelines | |
| When modifying existing code, follow these patterns: | |
| ### Replace `export let` with `$props` | |
| ```svelte | |
| // ❌ Old | |
| export let title; | |
| export let count = 0; | |
| // ✅ New | |
| const { title, count = 0 } = $props(); | |
| ``` | |
| ### Replace `$:` reactive declarations with `$derived` | |
| ```svelte | |
| // ❌ Old | |
| $: doubled = count * 2; | |
| // ✅ New | |
| let doubled = $derived(count * 2); | |
| ``` | |
| ### Replace `$:` reactive statements with `$effect` | |
| ```svelte | |
| // ❌ Old | |
| $: if (count > 5) { | |
| console.log('Count is high!'); | |
| } | |
| // ✅ New | |
| $effect(() => { | |
| if (count > 5) { | |
| console.log('Count is high!'); | |
| } | |
| }); | |
| ``` | |
| ### Replace lifecycle methods with `$effect` | |
| ```svelte | |
| // ❌ Old | |
| import { onMount, onDestroy } from 'svelte'; | |
| onMount(() => { | |
| console.log('Component mounted'); | |
| return () => { | |
| console.log('Component destroyed'); | |
| }; | |
| }); | |
| // ✅ New | |
| $effect(() => { | |
| console.log('Component mounted'); | |
| return () => { | |
| console.log('Component destroyed'); | |
| }; | |
| }); | |
| ``` | |
| ## Best Practices | |
| 1. **Use `$state` for component state** - All reactive data should use `$state` | |
| 2. **Derive instead of duplicate** - Use `$derived` instead of storing computed values separately | |
| 3. **Keep effects simple** - Use `$effect` for side effects, not data transformation | |
| 4. **Type your props** - Use TypeScript interfaces with `$props()` for type safety | |
| 5. **Avoid unnecessary effects** - Not every reactive change needs an effect; use `$derived` first | |
| 6. **Clean up side effects** - Return cleanup functions from `$effect` when needed | |
| 7. **Use `$effect.pre` sparingly** - Only when you need to react before the DOM updates | |
| ## Example Component | |
| ```svelte | |
| <script lang="ts"> | |
| interface Props { | |
| initialCount?: number; | |
| onCountChange?: (count: number) => void; | |
| } | |
| const { initialCount = 0, onCountChange } = $props(); | |
| let count = $state(initialCount); | |
| let doubled = $derived(count * 2); | |
| let message = $derived( | |
| count > 10 ? 'Count is high!' : 'Count is low.' | |
| ); | |
| $effect(() => { | |
| onCountChange?.(count); | |
| }); | |
| $effect(() => { | |
| document.title = `Count: ${count}`; | |
| return () => { | |
| document.title = 'Default'; | |
| }; | |
| }); | |
| </script> | |
| <div> | |
| <p>{message}</p> | |
| <p>Current: {count}, Doubled: {doubled}</p> | |
| <button onclick={() => count++}>Increment</button> | |
| <button onclick={() => count--}>Decrement</button> | |
| </div> | |
| ``` | |
| ## Resources | |
| - [Svelte 5 Docs - Runes](https://svelte.dev/docs/svelte/overview) | |
| - [Svelte 5 Migration Guide](https://svelte.dev/docs/svelte/v5-migration-guide) | |
| ## Summary | |
| **When writing code for this project:** | |
| - Always use Svelte 5 Runes | |
| - Use `$state` for reactive variables | |
| - Use `$derived` for computed values | |
| - Use `$effect` for side effects | |
| - Use `$props` for component properties | |
| - Avoid legacy patterns (`export let`, `$:`, lifecycle imports) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment