Svelte Stores: Your App’s Shared Memory Box
The Big Idea
Imagine you have a magic whiteboard in the middle of your house. Anyone in your family can write on it, and whenever someone writes something new, everyone else sees the change instantly!
That’s exactly what Svelte Stores do for your app. They’re like a shared notebook that all parts of your app can read and write to.
Why Do We Need Stores?
Picture this: You have a toy in your bedroom, and your sister wants to play with it from the living room. She can’t reach it!
In an app, different parts (called components) sometimes need to share information. Without stores, passing data around is like playing telephone—messy and confusing!
Stores solve this. They put your shared data in one place where everyone can see it.
🟢 Writable Stores
What Is It?
A writable store is like a box where you can:
- Look inside (read the value)
- Put something new inside (change the value)
- Get notified when someone changes it
Simple Example
import { writable } from 'svelte/store';
// Create a box with "5" inside
const count = writable(5);
// Look inside the box
count.subscribe(value => {
console.log('Count is now:', value);
});
// Put a new number inside
count.set(10);
// Add to what's already inside
count.update(n => n + 1);
Real Life Comparison
Think of a scoreboard at a basketball game:
- Anyone can look at it (subscribe)
- The scorekeeper can change it (set)
- Adding points? Just update! (update)
🔵 Readable Stores
What Is It?
A readable store is like a clock on the wall. You can look at it anytime, but you can’t change the time yourself—it updates on its own!
Simple Example
import { readable } from 'svelte/store';
// A clock that ticks every second
const time = readable(new Date(), function start(set) {
const interval = setInterval(() => {
set(new Date());
}, 1000);
// Cleanup when nobody's watching
return function stop() {
clearInterval(interval);
};
});
When to Use?
- Current time
- Mouse position
- Data from an external source
- Anything you want to share but not let others change
⚡ Store Auto-subscription
The Magic Dollar Sign
Svelte has a superpower: the $ prefix. Put it before any store name, and Svelte automatically:
- Subscribes when the component loads
- Updates whenever the store changes
- Unsubscribes when the component is destroyed
Before (The Hard Way)
<script>
import { count } from './stores.js';
let countValue;
const unsubscribe = count.subscribe(v => {
countValue = v;
});
// Don't forget to clean up!
import { onDestroy } from 'svelte';
onDestroy(unsubscribe);
</script>
<p>{countValue}</p>
After (The Easy Way)
<script>
import { count } from './stores.js';
</script>
<p>{$count}</p>
That’s it! The $ does all the work.
You Can Even Set Values!
<button on:click={() => $count += 1}>
Add One
</button>
🔗 Derived Stores
What Is It?
A derived store is like a calculator that watches other stores and computes something new automatically.
Everyday Example
Imagine you have:
- A store for price = $10
- A store for quantity = 3
A derived store can automatically calculate total = $30!
Code Example
import { writable, derived } from 'svelte/store';
const price = writable(10);
const quantity = writable(3);
// Automatically calculates!
const total = derived(
[price, quantity],
([$price, $quantity]) => $price * $quantity
);
// total is now 30
// Change price to 20... total becomes 60!
Multiple Sources
import { derived } from 'svelte/store';
const fullName = derived(
[firstName, lastName],
([$first, $last]) => `${$first} ${$last}`
);
🛠️ Custom Stores
What Is It?
Sometimes you want a store that does special tricks. A custom store wraps a regular store and adds your own methods!
Think of It Like…
A piggy bank that only lets you:
- Add coins (increment)
- Check how much you have (subscribe)
- Empty it (reset)
But you can’t just set any random number!
Code Example
import { writable } from 'svelte/store';
function createCounter() {
const { subscribe, set, update } = writable(0);
return {
subscribe, // Let others watch
increment: () => update(n => n + 1),
decrement: () => update(n => n - 1),
reset: () => set(0)
};
}
const counter = createCounter();
// Use it!
counter.increment(); // 1
counter.increment(); // 2
counter.reset(); // 0
Why Use Custom Stores?
- Control what changes are allowed
- Simplify complex operations
- Hide the messy details
- Reuse the same logic everywhere
📜 Store Contract
The Rules Every Store Must Follow
For something to be a “store” in Svelte, it must have one thing:
A
subscribemethod that returns anunsubscribefunction
That’s it! If you follow this rule, Svelte’s $ syntax works automatically.
The Contract Looks Like This
const myStore = {
subscribe(callback) {
// Call callback with current value
callback(currentValue);
// Return a function to stop listening
return function unsubscribe() {
// Clean up
};
}
};
Why Does This Matter?
You can use any library that follows this pattern with Svelte! For example, RxJS observables work because they follow the same contract.
graph TD A["Your Component"] -->|subscribe| B["Store"] B -->|callback with value| A A -->|unsubscribe| B B -->|stops updates| A
🎯 The get Function
The Quick Peek
Sometimes you just want to look once at a store’s value without subscribing. The get function does exactly that!
Code Example
import { get, writable } from 'svelte/store';
const count = writable(42);
// Quick peek - no subscription!
const currentValue = get(count);
console.log(currentValue); // 42
When to Use get()
✅ Good for:
- One-time reads in event handlers
- Checking value before doing something
- Non-reactive contexts
❌ Don’t use for:
- Keeping things in sync (use
$instead) - Regular template values (use
$instead)
Real Example
function handleClick() {
// Just need to know current value once
const current = get(count);
if (current > 10) {
console.log('Count is high!');
}
}
Summary: When to Use What?
graph TD A["Need shared data?"] -->|Yes| B{Can others change it?} B -->|Yes| C["Writable Store"] B -->|No| D["Readable Store"] A -->|Combine stores?| E["Derived Store"] A -->|Custom methods?| F["Custom Store"] A -->|Quick peek?| G["get function"]
| Store Type | Use When… |
|---|---|
| Writable | Anyone can read AND write |
| Readable | Read-only, updates itself |
| Derived | Computed from other stores |
| Custom | You need special methods |
| get() | One-time value check |
Quick Reference
// WRITABLE - read & write
const box = writable(0);
box.set(5);
box.update(n => n + 1);
// READABLE - read only
const clock = readable(new Date(), set => {...});
// AUTO-SUBSCRIBE - the easy way
{$box}
// DERIVED - computed values
const sum = derived([a, b], ([$a, $b]) => $a + $b);
// CUSTOM - your own methods
function createStore() {
const { subscribe, set } = writable(0);
return { subscribe, reset: () => set(0) };
}
// GET - one-time peek
const value = get(box);
You Did It!
Now you understand Svelte Stores:
- Writable = Shared box anyone can change
- Readable = Clock on the wall
- Auto-subscribe = The magic
$ - Derived = Automatic calculator
- Custom = Your special piggy bank
- Contract = The rules stores follow
- get() = Quick peek without commitment
Go build something amazing! 🚀
