Skip to main content
Svelte Fundamentals
CHAPTER 19 Beginner

Context API and Advanced State Management

Updated: May 18, 2026
5 min read

# CHAPTER 19

Context API and Advanced State Management

1. Chapter Introduction

When a deeply nested component needs data from a distant ancestor, prop drilling through every intermediate component is painful. Svelte's Context API (setContext/getContext) provides a clean solution. Combined with advanced store patterns, you can build sophisticated, scalable state management for large applications.

2. Learning Objectives

  • Use setContext and getContext to share data in component trees.
  • Understand the difference between Context and Stores.
  • Build custom store factories.
  • Implement the store pattern for complex features.

3. Context API: setContext / getContext

svelte
123456789101112131415
<!-- ThemeProvider.svelte (ancestor) -->
<script>
  import { setContext } from &#039;svelte';
  import { writable } from &#039;svelte/store';

  const theme = writable(&#039;light');

  // Set context — available to ALL descendants
  setContext(&#039;theme', {
    theme,
    toggleTheme: () => theme.update(t => t === &#039;light' ? 'dark' : 'light')
  });
</script>

<slot />
svelte
12345678910
<!-- DeepNestedButton.svelte (deep descendant — no props needed!) -->
<script>
  import { getContext } from &#039;svelte';

  const { theme, toggleTheme } = getContext(&#039;theme');
</script>

<button on:click={toggleTheme} class:dark={$theme === &#039;dark'}>
  {$theme === &#039;light' ? '🌙 Dark Mode' : '☀️ Light Mode'}
</button>
svelte
123456789
<!-- App.svelte -->
<script>
  import ThemeProvider from &#039;./ThemeProvider.svelte';
  import Dashboard from &#039;./Dashboard.svelte';
</script>

<ThemeProvider>
  <Dashboard />  <!-- Dashboard can use DeepNestedButton anywhere inside! -->
</ThemeProvider>

4. Context vs Stores

FeatureContextStores
ScopeSubtree of descendantsEntire application
ReactiveYes (with stores inside)Yes
SSR safeYes (per-request)Careful (shared across requests)
Use caseUI themes, shared config for a featureGlobal auth, cart, preferences

5. Custom Store Factory

A store factory creates configurable store instances — perfect for features that need multiple independent instances:
javascript
1234567891011121314
// src/lib/stores/counterStore.js
import { writable, derived } from &#039;svelte/store&#039;;

export function createCounter(initialValue = 0, step = 1) {
  const { subscribe, set, update } = writable(initialValue);

  return {
    subscribe,
    increment: () => update(n => n + step),
    decrement: () => update(n => n - step),
    reset: () => set(initialValue),
    double: derived({ subscribe }, $n => $n * 2)
  };
}
svelte
12345678910111213
<!-- Using two independent counter instances -->
<script>
  import { createCounter } from &#039;$lib/stores/counterStore.js';

  const cartCount = createCounter(0, 1);
  const notificationCount = createCounter(0, 1);
</script>

<p>Cart: {$cartCount}</p>
<button on:click={cartCount.increment}>Add to cart</button>

<p>Notifications: {$notificationCount}</p>
<button on:click={notificationCount.increment}>New notification</button>

6. Auth Store Pattern

javascript
12345678910111213141516171819202122232425262728293031323334353637
// src/lib/stores/authStore.js
import { writable, derived } from &#039;svelte/store&#039;;

function createAuthStore() {
  const { subscribe, set, update } = writable({
    user: null,
    token: null,
    loading: false
  });

  return {
    subscribe,
    login: async (email, password) => {
      update(s => ({ ...s, loading: true }));
      try {
        const res = await fetch(&#039;/api/login&#039;, {
          method: &#039;POST&#039;,
          body: JSON.stringify({ email, password }),
          headers: { &#039;Content-Type&#039;: &#039;application/json&#039; }
        });
        const { user, token } = await res.json();
        set({ user, token, loading: false });
        localStorage.setItem(&#039;token&#039;, token);
      } catch {
        update(s => ({ ...s, loading: false }));
      }
    },
    logout: () => {
      set({ user: null, token: null, loading: false });
      localStorage.removeItem(&#039;token&#039;);
    }
  };
}

export const auth = createAuthStore();
export const isLoggedIn = derived(auth, $auth => !!$auth.user);
export const currentUser = derived(auth, $auth => $auth.user);
svelte
1234567891011
<!-- Navbar.svelte -->
<script>
  import { auth, isLoggedIn, currentUser } from &#039;$lib/stores/authStore.js';
</script>

{#if $isLoggedIn}
  <span>Welcome, {$currentUser.name}!</span>
  <button on:click={auth.logout}>Logout</button>
{:else}
  <a href="/login">Login</a>
{/if}

7. Common Mistakes

  • Using context for global state: Context is scoped to a component subtree. For truly global state (available everywhere), use a module-level store instead.
  • Setting context in onMount: setContext must be called during component initialization (synchronously in <script>), not inside onMount.

8. MCQs

Question 1

What function provides data to all descendant components?

Question 2

What function retrieves context in a descendant component?

Question 3

When must setContext be called?

Question 4

What is the primary use case for Context vs Stores?

Question 5

What does a custom store factory return?

Q6. Why is Context preferred over Stores for SSR (server-side rendering)? a) Performance b) Context is per-request; module-level stores are shared across all server requests — Answer: b
Question 7

How do you make context reactive in Svelte?

Question 8

Can you have multiple independent instances of a store?

Question 9

What is prop drilling and why is it a problem?

Question 10

How does derived work with a custom store?

9. Interview Questions

  • Q: When would you choose setContext/getContext over a Svelte store for shared state?
  • Q: What is a store factory pattern and what problem does it solve?

10. Summary

Svelte's Context API solves prop drilling elegantly. Custom store factories enable configurable, reusable state machines. Together with standard stores for global state, these patterns cover every real-world state management scenario in production Svelte applications.

11. Next Chapter Recommendation

In
Chapter 20: Authentication and Authorization**, we build a complete JWT-based auth system with protected routes, login/logout flow, and role-based access control.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·