1

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?

1
  • onMount is not deprecated in Svelte 5 and it allows async functions. The auto-migration script helps with the bulk of the migration, but it isn't so smart and can change certain things without need, as intent is hard to fully algorithmically predict. After running the auto-migrate, it's best to look over the diffs, and change anything that doesn't look correct manually, the replacement of onMount in places where it was needed is one of such cases likely. Commented Apr 29 at 22:22

1 Answer 1

1

You can just keep using onMount, there is no real reason not to.

$effect does not accept async functions because await breaks its dependency tracking. If you really want to use $effect anyway, you can use an IIFE as shown or extract the logic to a separate function. You just should be aware of how async code behaves in an $effect.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.