Skip to content

Built-in Stores

writable(initial) from svelte/store creates a store you can read and write. It has three methods: set(value) (replace), update(fn) (change based on the current value), and subscribe(fn) (the contract).

stores/count.js
import { writable } from 'svelte/store';
export const count = writable(0);
<script>
import { count } from './stores/count.js';
</script>
<button onclick={() => count.update((n) => n + 1)}>increment</button>
<button onclick={() => count.set(0)}>reset</button>
<p>{$count}</p> <!-- $ reads the value and re-renders -->

Any component that imports count shares the same store — writing in one place updates everywhere it’s read. That’s shared state in one line.

readable — a value you can’t set from outside

Section titled “readable — a value you can’t set from outside”

readable(initial, start) creates a store whose value is controlled by a start function, not by consumers. The start function receives set (and update), runs when the first subscriber arrives, and returns a stop function that runs when the last subscriber leaves — perfect for wrapping a push-based source.

// stores/time.js — a clock nobody can set from outside
import { readable } from 'svelte/store';
export const time = readable(new Date(), (set) => {
const id = setInterval(() => set(new Date()), 1000);
return () => clearInterval(id); // cleanup when no one is listening
});

The start/stop lifecycle means the interval only runs while something is actually subscribed — no wasted work.

derived(source, fn) builds a new store from one or more existing stores, recomputing when any source changes.

import { derived } from 'svelte/store';
import { count } from './count.js';
export const doubled = derived(count, ($count) => $count * 2);
// From multiple stores — pass an array:
export const summary = derived(
[count, doubled],
([$count, $doubled]) => `${$count} doubled is ${$doubled}`
);
flowchart LR
  w["writable: set, update, subscribe"] --> use["read with $ in a component"]
  r["readable: start/stop controls the value"] --> use
  d["derived: computed from other stores"] --> use
The three built-in stores

With runes available, reach for stores when you specifically want the contract: wrapping an external push source (readable around a WebSocket), interoperating with observables, or working in existing store-based code. For plain app state shared across components, a runed module (next lesson) is usually simpler.

What three methods does a `writable` store have?
What is special about a `readable` store's start function?
What does `derived(count, $count => $count * 2)` produce?
When should you still prefer a store over runes?