Component Lifecycle with onMount
Running setup code once a component is mounted to the DOM, and cleaning it up when it's destroyed.
អាន 2 នាទី
$effect (covered earlier in this course) reruns every time its dependencies change — that's exactly what you want for keeping something in sync with reactive state. But some setup work should only ever happen once, when a component first appears in the DOM, regardless of what state does afterward. That's what onMount is for.
<script>
import { onMount } from 'svelte';
let width = $state(0);
onMount(() => {
width = window.innerWidth;
});
</script>
<p>Window width at mount: {width}px</p>onMount's callback runs once, after the component's DOM elements exist. That timing matters for anything that needs to touch the real DOM — measuring an element's size, focusing an input, initializing a third-party library that expects a DOM node to already be there.
Cleaning up on destroy
Like $effect, onMount can return a cleanup function, which runs when the component is removed from the DOM:
<script>
import { onMount } from 'svelte';
let width = $state(window.innerWidth);
onMount(() => {
function handleResize() {
width = window.innerWidth;
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
});
</script>
<p>Width: {width}px</p>Without that returned cleanup, the listener would keep firing (and keep a reference to the component alive) even after the component's markup is long gone from the page — a memory leak that gets worse the more times the component mounts and unmounts over a session.
onMount vs. $effect
They overlap, but reach for the right one on purpose:
onMountruns exactly once, after the component's first render, and never reruns no matter what state changes afterward. Use it for one-time setup that genuinely doesn't depend on reactive values — readingwindowdimensions, initializing a map or chart library against a DOM node.$effectreruns whenever any reactive value it reads changes, including once after the initial render. Use it whenever the side effect should track state over time — the interval and search examples from the$effectlesson both needed to react to changing values, whichonMountalone can't do.
If you're not sure which applies, ask whether the logic needs to happen again when some piece of state changes. If yes, it's $effect. If it's truly a one-time setup step, onMount says that intent more clearly.
Server-side rendering note
onMount deliberately never runs during server-side rendering (relevant once you move to SvelteKit) — only in the browser, after the component reaches real DOM. Code that assumes window or document exist belongs in onMount, never directly in the top level of <script>, precisely so it doesn't break in an environment where there is no browser at all.