0
0
Svelteframework~15 mins

Readable stores in Svelte - Deep Dive

Choose your learning style9 modes available
Overview - Readable stores
What is it?
Readable stores in Svelte are special objects that hold data you can watch but not change directly. They let parts of your app know when data updates, so the app can react and show the latest information. Unlike writable stores, readable stores only allow reading and subscribing, keeping the data safe from accidental changes.
Why it matters
Readable stores exist to share data safely across your app without letting every part change it. Without readable stores, managing shared data would be messy and error-prone, causing bugs and confusing updates. They help keep your app organized and predictable, making it easier to build and maintain.
Where it fits
Before learning readable stores, you should understand basic Svelte components and reactive statements. After mastering readable stores, you can explore writable stores for two-way data changes and derived stores for computed data. This fits into the bigger picture of state management in Svelte apps.
Mental Model
Core Idea
A readable store is like a secure mailbox you can check anytime but only the owner can put letters in.
Think of it like...
Imagine a public bulletin board in a community center. Everyone can read the notices posted there, but only the manager can put up or change the notices. This keeps the information reliable and prevents confusion from random changes.
┌───────────────┐
│ Readable Store│
│  (data holder)│
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Subscribers   │
│ (components)  │
└───────────────┘

Data flows one-way: Store updates → Subscribers notified
Subscribers cannot change the store directly.
Build-Up - 7 Steps
1
FoundationUnderstanding Svelte stores basics
🤔
Concept: Learn what a store is and how it helps share data reactively in Svelte.
In Svelte, a store is an object that holds a value and lets components subscribe to changes. When the value changes, all subscribers get notified automatically. This helps keep UI in sync with data without manual updates.
Result
You understand that stores are reactive data containers that notify subscribers on changes.
Knowing stores are reactive data holders is key to managing shared state in Svelte apps.
2
FoundationDifference between readable and writable stores
🤔
Concept: Distinguish readable stores from writable stores by their ability to change data.
Writable stores let you read and write data, while readable stores only let you read and subscribe. Readable stores protect data from being changed by components, making data flow safer and more predictable.
Result
You can identify when to use readable stores to prevent unwanted data changes.
Understanding this difference helps you choose the right store type for your app's needs.
3
IntermediateCreating a readable store in Svelte
🤔Before reading on: Do you think you can create a readable store with a simple function call or do you need complex setup? Commit to your answer.
Concept: Learn how to create a readable store using Svelte's built-in function and provide a way to update its value internally.
Use the 'readable' function from 'svelte/store' to create a readable store. It takes an initial value and a start function that sets up how the store updates internally. Components can subscribe but cannot change the value directly.
Result
You can create a readable store that shares data safely and updates subscribers when data changes internally.
Knowing how to create readable stores lets you control data flow and protect state from external changes.
4
IntermediateSubscribing to readable stores in components
🤔Before reading on: Do you think subscribing to a readable store requires manual cleanup or does Svelte handle it automatically? Commit to your answer.
Concept: Learn how components listen to readable stores and update automatically when data changes.
In Svelte components, use the '$' prefix to auto-subscribe to stores. For readable stores, this means the component reacts to changes without extra code. Svelte also cleans up subscriptions when components unmount.
Result
Components reactively update their UI when readable store data changes, with no manual subscription management.
Understanding Svelte's auto-subscription simplifies reactive UI updates and prevents memory leaks.
5
IntermediateUsing readable stores for external data sources
🤔
Concept: Use readable stores to wrap data that changes outside Svelte, like timers or web APIs.
Readable stores are perfect for data that updates on its own, such as the current time or data from a WebSocket. The start function can set up listeners or intervals that update the store internally, keeping components in sync.
Result
You can integrate external or asynchronous data sources into your Svelte app reactively and safely.
Knowing readable stores can wrap external data sources expands your app's reactive capabilities.
6
AdvancedCleaning up readable store subscriptions internally
🤔Before reading on: Do you think the start function in readable stores can return a cleanup function? Commit to your answer.
Concept: Learn how to properly clean up resources like timers or event listeners inside readable stores to avoid leaks.
The start function passed to 'readable' can return a cleanup function. This function runs when the last subscriber unsubscribes, letting you stop timers or remove event listeners to free resources.
Result
Your readable stores manage resources efficiently, preventing memory leaks and unnecessary work.
Understanding cleanup in readable stores is crucial for building performant and robust apps.
7
ExpertReadable stores internals and subscription management
🤔Before reading on: Do you think readable stores notify subscribers immediately on subscription or only on changes? Commit to your answer.
Concept: Explore how readable stores manage subscribers, notify them, and handle multiple subscriptions efficiently.
Readable stores keep a list of subscribers and notify them immediately with the current value when they subscribe. They only run the start function once when the first subscriber appears and run cleanup when the last leaves. This optimizes resource use and ensures consistent data delivery.
Result
You understand the internal lifecycle of readable stores and how they optimize updates and resource management.
Knowing the subscription lifecycle helps you design stores that are efficient and predictable in complex apps.
Under the Hood
Readable stores internally maintain a list of subscriber functions. When a component subscribes, the store calls the subscriber immediately with the current value. The store runs a start function once when the first subscriber subscribes, which can set up data sources or timers. When the last subscriber unsubscribes, the store calls the cleanup function returned by start to free resources. Updates to the store's value trigger calls to all subscribers with the new value.
Why designed this way?
This design ensures that resources like timers or event listeners only run when needed, saving CPU and memory. Immediate notification on subscription guarantees components always have the latest data. Separating read-only access prevents accidental data changes, making apps more reliable and easier to debug.
┌───────────────┐
│ Readable Store│
│  (value, subs)│
└──────┬────────┘
       │ start() called once
       ▼
┌───────────────┐
│ Data source   │
│ (timer, API)  │
└──────┬────────┘
       │ updates value
       ▼
┌───────────────┐
│ Subscribers   │
│ (functions)   │
└───────────────┘

On first subscriber: start() runs
On last unsubscribe: cleanup runs
On update: notify all subscribers
Myth Busters - 4 Common Misconceptions
Quick: Can components change the value of a readable store directly? Commit yes or no.
Common Belief:Components can change readable store values just like writable stores.
Tap to reveal reality
Reality:Readable stores do not expose any method to change their value from outside; only the internal start function can update it.
Why it matters:Trying to change readable stores directly leads to errors or confusion, breaking the intended data flow and causing bugs.
Quick: Does subscribing to a readable store require manual cleanup in components? Commit yes or no.
Common Belief:You must manually unsubscribe from readable stores to avoid memory leaks.
Tap to reveal reality
Reality:Svelte automatically handles subscription cleanup when components unmount, so manual cleanup is usually unnecessary.
Why it matters:Believing manual cleanup is needed can cause overcomplicated code and distract from focusing on app logic.
Quick: Do readable stores notify subscribers only when the value changes or also immediately on subscription? Commit your answer.
Common Belief:Readable stores notify subscribers only when the value changes after subscription.
Tap to reveal reality
Reality:Readable stores notify subscribers immediately with the current value upon subscription.
Why it matters:Not knowing this can cause confusion about why components update instantly, leading to incorrect assumptions about store behavior.
Quick: Can readable stores be used to wrap asynchronous or external data sources? Commit yes or no.
Common Belief:Readable stores are only for static or simple data, not for async or external sources.
Tap to reveal reality
Reality:Readable stores are ideal for wrapping asynchronous or external data like timers, WebSockets, or APIs.
Why it matters:Missing this limits your ability to build reactive apps that integrate real-world data efficiently.
Expert Zone
1
Readable stores run their start function only once, no matter how many subscribers exist, optimizing resource usage.
2
The cleanup function returned by the start function runs only when the last subscriber unsubscribes, preventing premature resource disposal.
3
Readable stores notify subscribers immediately on subscription, ensuring components always have the latest data without waiting for changes.
When NOT to use
Avoid readable stores when you need components to update the store's value directly; use writable stores instead. For computed or derived data based on other stores, use derived stores. If you need complex state management with actions and reducers, consider external libraries like Svelte's context or state machines.
Production Patterns
In production, readable stores often wrap external APIs, timers, or WebSocket connections to provide reactive data streams. They are used to expose read-only global state like user authentication status or system settings. Combining readable stores with derived stores creates efficient, layered reactive data flows.
Connections
Observer pattern
Readable stores implement the observer pattern by letting subscribers watch for data changes.
Understanding readable stores as an observer pattern helps grasp how reactive updates propagate in many programming contexts.
Immutable data structures
Readable stores promote immutability by preventing external writes, similar to immutable data principles.
Knowing this connection clarifies why readable stores improve reliability and reduce bugs by controlling data changes.
Publish-subscribe messaging systems
Readable stores act like pub-sub systems where data publishers notify subscribers of updates.
Recognizing readable stores as lightweight pub-sub systems helps in designing scalable reactive architectures.
Common Pitfalls
#1Trying to update a readable store directly from a component.
Wrong approach:import { readable } from 'svelte/store'; const time = readable(new Date(), set => { const interval = setInterval(() => set(new Date()), 1000); return () => clearInterval(interval); }); // In component function updateTime() { time.set(new Date()); // Error: set is not a function }
Correct approach:import { readable } from 'svelte/store'; const time = readable(new Date(), set => { const interval = setInterval(() => set(new Date()), 1000); return () => clearInterval(interval); }); // In component // Just subscribe or use $time to get updates, no direct set
Root cause:Misunderstanding that readable stores do not expose a set method to external code.
#2Not cleaning up resources inside the readable store's start function.
Wrong approach:const timer = readable(new Date(), set => { setInterval(() => set(new Date()), 1000); // No cleanup function returned });
Correct approach:const timer = readable(new Date(), set => { const interval = setInterval(() => set(new Date()), 1000); return () => clearInterval(interval); });
Root cause:Forgetting that the start function should return a cleanup function to avoid resource leaks.
#3Manually unsubscribing from readable stores inside Svelte components unnecessarily.
Wrong approach:let unsubscribe; onMount(() => { unsubscribe = time.subscribe(value => { // do something }); }); onDestroy(() => { unsubscribe(); });
Correct approach:
Root cause:Not realizing Svelte auto-manages subscriptions with the $ prefix syntax.
Key Takeaways
Readable stores provide a safe way to share reactive data that components can read but not change directly.
They are ideal for wrapping external or asynchronous data sources like timers or APIs.
Svelte automatically manages subscriptions to readable stores, simplifying component code and preventing leaks.
The start function in readable stores sets up data updates and can return a cleanup function to free resources.
Understanding readable stores' internal subscription lifecycle helps build efficient and predictable reactive apps.