Under The Hood
frontend svelte Svelte 5 (snippets stable)

Svelte 5 snippets vs slots

Last updated
Prerequisites:
Svelte component basics
Experience with named/default slots in Svelte 4
  • svelte
  • snippets
  • slots
  • composition
  • svelte5
  • templates

Read at your depth

The practical view

Slots let a parent project content into a child: <Card><p>hello</p></Card> fills Card's default <slot />. Snippets change the model: the child declares {@render header()} where it wants content, and the parent defines {#snippet header()}...{/snippet} and passes it as header. Snippets are first-class values: you can pass multiple named ones, reuse one snippet in several places inside the child, and even pass a snippet to a snippet ({@render} with args — parameterized content like {#snippet row(item)}). With snippets you can pass snippets from one component to another as props, which slots could not do cleanly.

The same idea in other frameworks

react equivalent
// React: children props and render props
<Card header={(h) => <h2>{h}</h2>}>…</Card>

Legacy vs modern

Named slots vs snippets with parameters

Slots only pass markup into fixed holes; snippets are functions that can take arguments, be reused, and be forwarded — enabling parameterized row rendering.

before → after
Svelte 4 slots
<Card>
  <svelte:fragment slot="footer">
    <p>Done</p>
  </svelte:fragment>
</Card>
Svelte 5 snippets
{#snippet row(item)}<li><strong>{item.name}</strong></li>{/snippet}
<List {items} {row} />

Interview gotchas

Context

This checks whether the candidate understands content projection as data flow, not just 'a nicer syntax for slots'.

The mechanical answer

Snippets are functions: they can take parameters (so a list can call the same snippet per item with real data), be rendered multiple times, be forwarded through wrapper components as ordinary props, and be typed. Slots were fixed, named holes that required a slot-proxy mechanism and special forwarding ($$slots, slot inheritance) to pass through wrappers. With snippets, a component's content contract becomes an explicit, typed prop list, which makes the API introspectable, testable, and safe to refactor. The design consequence is that libraries move from 'slot conventions' to 'documented snippet props', and composition such as higher-order layouts becomes plain function passing.

Trap

The naive answer is 'snippets are just named slots'. They are a different mechanism: slots are a runtime projection mechanism with a slot object; snippets are compiled-down function props called with {@render}. Also, candidates often claim snippets replaced slots entirely — Svelte 5 still supports <slot> for compatibility, but new code uses snippets, and the slot mechanism is legacy. Mentioning parameterized rendering ({#snippet row(item)}) as the genuinely new capability is the differentiator.

Under The Hood — a multi-depth technical interview hub.

Third-party licenses Press ⌘ K to search.