Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save nickludlam/919bdf0d5274ffbe65af5cb5f26d133f to your computer and use it in GitHub Desktop.

Select an option

Save nickludlam/919bdf0d5274ffbe65af5cb5f26d133f to your computer and use it in GitHub Desktop.
LLM written Agents.md for Svelte 5
# 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