Svelte store subscriptions leaking after component unmount when subscribing manually in onMount
0 reputation · 03 Oct 2026, 09:15 UTC
0 reputation · 03 Oct 2026, 09:15 UTC
I want to share state between several Svelte components using a writable store defined in a separate .js module, while guaranteeing that no subscriptions survive after a component is destroyed.
The documented behavior is that the $store auto-subscription syntax inside .svelte files unsubscribes automatically on component destruction. However, some of my logic lives outside markup — for example, subscribing inside onMount or in a plain utility module — where the compiler cannot insert the cleanup for me. The documentation indicates manual subscribe() calls return an unsubscribe function that I must invoke myself, but it is unclear to me exactly which lifecycle hook is the correct place for that cleanup, and whether missing it produces a detectable failure (growing memory usage, duplicate handler invocations) or fails silently.
Assume Svelte 4/5-era store contracts (writable, derived from svelte/store); if runes-based state changes this answer, that distinction matters.
onMount, is returning the unsubscribe function from onMount's cleanup the documented and sufficient pattern?30775 reputation · 03 Oct 2026, 14:39 UTC
1. Is returning the unsubscribe function from onMount the documented and sufficient pattern?
Yes. In Svelte 4 the onMount helper accepts a callback that can return a cleanup function. That cleanup is executed automatically when the component is destroyed, so you can write:
import { onMount } from 'svelte';
import { myStore } from './stores.js';
onMount(() => {
const unsubscribe = myStore.subscribe(value => {
// react to value
});
return () => unsubscribe(); // cleanup on unmount
});
This is the officially documented way (see the Svelte 4 docs under onMount) and is equivalent to calling onDestroy(() => unsubscribe());. Returning the function is concise and guarantees the subscription is torn down when the component leaves the DOM.
2. Is there a supported way to verify at runtime that all subscriptions were released after unmount, short of heap profiling?
console.log inside the subscription callback and confirm it stops firing after the component is removed.--check-usage flag in the Svelte compiler to catch unused stores, though it does not detect live leaks.There is no built‑in runtime assertion that a store has been unsubscribed; the framework simply relies on the cleanup you provide.
3. Does a leaked subscription cause any observable warning in development mode, or is it always silent?
Leaked subscriptions are silent. Svelte does not emit a warning if a subscription callback continues to run after the component has been destroyed. You may see errors if the callback tries to manipulate DOM nodes that no longer exist, but otherwise the leak will not be reported.
onMount (or any lifecycle hook) and store the returned unsubscribe function.onMount callback, or call it in onDestroy.derived stores that internally subscribe to other stores, remember that unsubscribing from the outer store automatically tears down the inner subscriptions.Using the return form keeps your component code compact and eliminates the risk of forgetting to clean up. If you prefer explicit cleanup, onDestroy works just as well.
If you are subscribing to a derived store that internally listens to other stores, let me know, because the unsubscribe chain can be slightly different.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.