I'm migrating my project from Svelte 4 to Svelte 5, and one major pain point is the removal of the traditional onMount usage for async logic.
In Svelte 4, I used onMount(async () => { ... }) to fetch data from my backend and perform validations right after the component loads.
In Svelte 5, I understand that $effect and @effect are the new way to run side effects, but $effect does not accept an async function, and $effect doesn’t seem as intuitive when dealing with promises — especially with TypeScript complaining if you try to return a Promise.
What's the cleanest and most idiomatic way to run an async effect only once on component mount in Svelte 5? Is this pattern below acceptable?
$effect(() => {
(async () => {
const res = await fetch('/api/data');
data = await res.json();
})();
});
Or is there a better way to handle this common pattern?
During the automatic migration from Svelte 4 to Svelte 5, I noticed that all onMount functions were removed and replaced by the run function from the svelte/legacy module.
This worked as a temporary compatibility layer, but now I want to follow the recommended approach using runes like $effect instead of relying on legacy APIs. However, I'm still unsure what the best pattern is to handle async logic that should only run once after the component mounts — which is what I used onMount for.
Any guidance on the cleanest way to do this with the new runes?