Skip to content

The Context API

When many nested components need the same data — a theme, the current user, a form’s shared state — passing it through every intermediate component as props (prop drilling) is tedious and noisy. Context lets an ancestor set a value that any descendant can read directly.

  • setContext(key, value) — called in a component during initialization; makes value available to all descendants under key.
  • getContext(key) — called in any descendant; reads the nearest ancestor’s value for key.
Parent.svelte
<script>
import { setContext } from 'svelte';
setContext('theme', 'dark');
</script>
<slot-like-children />
<!-- DeepChild.svelte (any depth below) -->
<script>
import { getContext } from 'svelte';
const theme = getContext('theme'); // 'dark' — no props threaded through
</script>
<div class={theme}></div>
flowchart TB
  parent["Ancestor: setContext('theme', value)"] --> mid["intermediate components
(no props needed)"]
  mid --> child["Descendant: getContext('theme')"]
Context flows down to any descendant

setContext runs once, at init — the value it stores isn’t reactive by itself. To share reactive data, put a runed object into context and read its properties in descendants; because $state objects are deeply reactive, changes propagate.

<!-- Store a runed object, not a plain snapshot -->
<script>
import { setContext } from 'svelte';
let cart = $state({ items: [] });
setContext('cart', cart); // descendants see live updates to cart.items
</script>

A common pattern is a small factory that creates the runed state and pairs setContext/getContext behind typed helper functions, so consumers just call getCart().

  • Props — best for direct parent→child data. Explicit and easy to trace.
  • Context — best when data is needed by many descendants at varying depths (theme, auth, a widget’s shared state) and is scoped to a subtree.
  • Module state (.svelte.js) — best for truly app-global state, but mind SSR (a module singleton is shared across requests on the server — the state-management module covers this).

Crucially, context is per component tree and per render, so on the server each request gets its own context — making it the SSR-safe way to share request-scoped state, unlike a module-level singleton.

What problem does context solve?
How do you share reactive data through context?
Why is context safer than a module-level singleton for request-scoped state on the server?
When should you prefer props over context?