Anna University Plus Front-End JavaScript Svelte Svelte Stores vs Svelte 5 Runes: Which State Management Approach Should You Use?

Svelte Stores vs Svelte 5 Runes: Which State Management Approach Should You Use?

Svelte Stores vs Svelte 5 Runes: Which State Management Approach Should You Use?

 
  • 0 Vote(s) - 0 Average
 
Admin
Administrator
454
04-01-2026, 05:46 PM
#1
Svelte 5 introduced Runes as a new way to handle reactivity, replacing the traditional Svelte Stores approach. This thread compares both systems to help you decide which one fits your project.

Svelte Stores (Svelte 3/4)

Stores have been the standard way to share reactive state across components in Svelte.

Writable Store Example:

Code:

// stores.ts
import { writable } from 'svelte/store';
export const count = writable(0);
export const user = writable({ name: '', email: '' });

Code:

<!-- Component.svelte -->
<script>
  import { count } from './stores';
</script>
<p>Count: {$count}</p>
<button on:click={() => count.update(n => n + 1)}>Increment</button>

Derived Stores:

Code:

import { derived } from 'svelte/store';
import { count } from './stores';
export const doubled = derived(count, $count => $count * 2);

Svelte 5 Runes

Runes use a compiler-based approach with special $ prefixed functions.

$state Rune:

Code:

<script>
  let count = $state(0);
  let user = $state({ name: '', email: '' });
</script>
<p>Count: {count}</p>
<button onclick={() => count++}>Increment</button>

$derived Rune:

Code:

<script>
  let count = $state(0);
  let doubled = $derived(count * 2);
  let message = $derived.by(() => {
    if (count > 10) return 'High';
    return 'Low';
  });
</script>

$effect Rune:

Code:

<script>
  let count = $state(0);
 
  $effect(() => {
    console.log('Count changed:', count);
    // Cleanup function
    return () => console.log('Cleaning up');
  });
</script>

Comparison Table

| Feature | Stores | Runes |
|---------|--------|-------|
| Syntax | $store auto-subscription | Direct variable access |
| Sharing state | Import store anywhere | Use .svelte.ts files |
| Derived values | derived() function | $derived keyword |
| Side effects | store.subscribe() | $effect() |
| TypeScript | Manual typing needed | Automatic type inference |
| Bundle size | Runtime overhead | Compiled away |
| Learning curve | Moderate | Lower |

Sharing State with Runes

To share state across components with Runes, create a .svelte.ts file:

Code:

// counter.svelte.ts
let count = $state(0);
export function getCount() {
  return count;
}
export function increment() {
  count++;
}

When to Use Which?

- Use Runes if you are starting a new Svelte 5 project
- Keep Stores if you have an existing Svelte 3/4 codebase and migration is not urgent
- Runes offer better performance due to compile-time optimization
- Stores are still supported in Svelte 5 for backward compatibility

Migration Tips

1. Start by converting simple writable stores to $state
2. Replace derived stores with $derived
3. Convert store.subscribe() calls to $effect
4. Move shared state to .svelte.ts files
5. Test thoroughly after each conversion step

Which approach do you prefer? Share your thoughts!
Admin
04-01-2026, 05:46 PM #1

Svelte 5 introduced Runes as a new way to handle reactivity, replacing the traditional Svelte Stores approach. This thread compares both systems to help you decide which one fits your project.

Svelte Stores (Svelte 3/4)

Stores have been the standard way to share reactive state across components in Svelte.

Writable Store Example:

Code:

// stores.ts
import { writable } from 'svelte/store';
export const count = writable(0);
export const user = writable({ name: '', email: '' });

Code:

<!-- Component.svelte -->
<script>
  import { count } from './stores';
</script>
<p>Count: {$count}</p>
<button on:click={() => count.update(n => n + 1)}>Increment</button>

Derived Stores:

Code:

import { derived } from 'svelte/store';
import { count } from './stores';
export const doubled = derived(count, $count => $count * 2);

Svelte 5 Runes

Runes use a compiler-based approach with special $ prefixed functions.

$state Rune:

Code:

<script>
  let count = $state(0);
  let user = $state({ name: '', email: '' });
</script>
<p>Count: {count}</p>
<button onclick={() => count++}>Increment</button>

$derived Rune:

Code:

<script>
  let count = $state(0);
  let doubled = $derived(count * 2);
  let message = $derived.by(() => {
    if (count > 10) return 'High';
    return 'Low';
  });
</script>

$effect Rune:

Code:

<script>
  let count = $state(0);
 
  $effect(() => {
    console.log('Count changed:', count);
    // Cleanup function
    return () => console.log('Cleaning up');
  });
</script>

Comparison Table

| Feature | Stores | Runes |
|---------|--------|-------|
| Syntax | $store auto-subscription | Direct variable access |
| Sharing state | Import store anywhere | Use .svelte.ts files |
| Derived values | derived() function | $derived keyword |
| Side effects | store.subscribe() | $effect() |
| TypeScript | Manual typing needed | Automatic type inference |
| Bundle size | Runtime overhead | Compiled away |
| Learning curve | Moderate | Lower |

Sharing State with Runes

To share state across components with Runes, create a .svelte.ts file:

Code:

// counter.svelte.ts
let count = $state(0);
export function getCount() {
  return count;
}
export function increment() {
  count++;
}

When to Use Which?

- Use Runes if you are starting a new Svelte 5 project
- Keep Stores if you have an existing Svelte 3/4 codebase and migration is not urgent
- Runes offer better performance due to compile-time optimization
- Stores are still supported in Svelte 5 for backward compatibility

Migration Tips

1. Start by converting simple writable stores to $state
2. Replace derived stores with $derived
3. Convert store.subscribe() calls to $effect
4. Move shared state to .svelte.ts files
5. Test thoroughly after each conversion step

Which approach do you prefer? Share your thoughts!

 
  • 0 Vote(s) - 0 Average
Recently Browsing
 1 Guest(s)
Recently Browsing
 1 Guest(s)