Svelte 5 introduces runes as a unified reactivity model. The legacy mode provides backward compatibility with Svelte 4 syntax, but new projects should use runes.

Legacy let

In Svelte 4, let declarations were not reactive by default. Reactivity came through $: labels (reactive assignments) and export let (props).

Modern equivalent: Use $state() for reactive variables and $props() for component inputs.

Reactive Assignments ($:)

The $: label created reactive statements that re-ran when dependencies changed.

<!-- Svelte 4 -->
$: doubled = count * 2
$: console.log('count is', count)

Modern equivalent: $derived() for computed values, $effect() for side effects.

export let

Props were declared with export let in Svelte 4.

<!-- Svelte 4 -->
<script>
  export let name
  export let age = 18
</script>

Modern equivalent: $props() destructuring with default values.

$$props and $$restProps

$$props gave access to all passed props, $$restProps gave the props not explicitly declared.

Modern equivalent: Rest properties in $props() destructuring: let { explicit, ...rest } = $props().

on:event Directive

Svelte 4 used on:click, on:input, etc. for event handlers.

Modern equivalent: Use the onclick, oninput, etc. attribute syntax (lowercase, without colon), matching how HTML event handlers work.

Slots (<slot>)

Svelte 4 used <slot> elements and named slots for content projection.

<!-- Svelte 4 -->
<slot name="header" />
<slot />

Modern equivalent: Snippets with {@render} for more flexible and type-safe content projection.

$$slots

$$slots was an object indicating which slots were passed content.

Modern equivalent: Check if a snippet prop was provided (it will be undefined if not passed).

<svelte:fragment>

Used to wrap content without a container element, primarily for slot scenarios.

Modern equivalent: Not needed — snippets inherently provide fragment-like behavior.

<svelte:component>

Rendered a dynamic component based on a variable.

<svelte:component this={selectedComponent} />

Modern equivalent: Use <svelte:element> or conditional rendering with {#if}.

<svelte:self>

Allowed a component to include itself recursively.

Modern equivalent: Components can import and reference themselves directly in Svelte 5.

Imperative Component API (Svelte 4)

Components were created imperatively with new Component({ target, props }).

Modern equivalent: Use mount(Component, { target, props }) and unmount(component) from svelte.

See Also