Svelte 5 State Management
Learn how to manage state using Svelte's context and a class-based approach.
November 15, 2025
3 Minutes Read
The best way to handle state in Svelte 5 is with a class-based approach using Svelte's setContext and getContext. This allows us to access shared app state anywhere in the application without prop drilling.
Creating the file
Create a svelte.ts or svelte.js file. For this example, we will create the file src/lib/hooks/app.svelte.ts to manage our app state as shown below.
src/lib/hooks/app.svelte.ts
import { MediaQuery } from "svelte/reactivity";
import { setContext, getContext } from "svelte";
/** App state class-based management */
class UseApp {
isDarkMode = $state(false);
isMobile = $derived(new MediaQuery("max-width: 700px").current);
// Set default data
constructor(props: { [key: string]: any }) {
// Merge props into this instance
Object.assign(this, props);
// Add or remove dark class on body whenever `isDarkMode` changes
$effect(() => {
document.body.classList.toggle("dark", this.isDarkMode);
});
}
/** Toggle isDarkMode */
darkModeToggle = () => (this.isDarkMode = !this.isDarkMode);
}
/** Hook props (isDarkMode can be set when initializing the hook) */
export type UseAppProps = Pick<InstanceType<typeof UseApp>, "isDarkMode">;
/** Set app state */
export const setApp = (props: UseAppProps) => setContext("appState", new UseApp(props));
/** Use app state */
export const useApp = () => getContext<ReturnType<typeof setApp>>("appState");
Initializing the app state
After creating the Svelte app hook, you need to initialize it inside your app layout, such as src/routes/+layout.svelte or src/App.svelte for Vite.js projects.
src/routes/+layout.svelte
<script lang="ts">
import { setApp } from "$lib/hooks/app.svelte.js";
// Set app hook
const { children } = $props();
const app = setApp({ isDarkMode: false });
// We can use it right away
app.isDarkMode; // false
</script>
{@render children()}
Using the app state
Now we can use our app state inside any component without passing it as a prop. Simply import useApp and start using it.
src/lib/component/toggle-btn.svelte
<script lang="ts">
import { useApp } from "$lib/hooks/app.svelte.js";
import { Button } from "$lib/components/ui/button";
const app = useApp();
/** Toggle light and dark mode when clicking the button */
function onclick() {
app.darkModeToggle();
}
</script>
<Button {onclick}>Toggle theme</Button>