dev-resources.site
for different kinds of informations.
Changelog 2024/48 aka We 🖤 Svelte 5
We have rewritten our platform's frontend using Svelte 5, streamlining our workflow and refining our codebase to develop a more flexible and sustainable codebase. The following elements were notable.
What We Appreciate in Svelte 5
- Reusable Snippets Replacing Slots
- Callbacks Replacing Dispatchers
- Simplified Prop Handling with $props
- Improved Component Typing
- Explicit Reactivity with Runes
- Reduced Bundle Sizes
1. Reusable Snippets Replacing Slots
Svelte 5's new snippets system provides a powerful alternative to the slot-based system from Svelte 4. Where we previously used named slots with <svelte:fragment slot="name">
, we now leverage the more flexible snippet syntax {#snippet name()}
. This allows passing parameters to template fragments and maintaining reactivity, making complex UI patterns like recursive components and compound components more straightforward. Our modal and dropdown components benefit from this change, as content can be dynamically injected while preserving state and context.
<!-- Parent.svelte -->
<Card>
<svelte:fragment slot="title">
My Card Title
</svelte:fragment>
<svelte:fragment slot="content">
Card content here
</svelte:fragment>
</Card>
<!-- Card.svelte -->
<div class="card">
<div class="title">
<slot name="title" />
</div>
<div class="content">
<slot name="content" />
</div>
</div>
Svelte 4
<!-- Parent.svelte -->
<Card>
{#snippet title()}
My Card Title
{/snippet}
{#snippet content()}
Card content here
{/snippet}
</Card>
<!-- Card.svelte -->
<script>
let { title, content } = $props();
</script>
<div class="card">
<div class="title">
{@render title()}
</div>
<div class="content">
{@render content()}
</div>
</div>
Svelte 5
2. Callbacks Replacing Dispatchers
Component communication is more straightforward with Svelte 5's approach to props and callbacks compared to event dispatchers. Where Svelte 4 required using createEventDispatcher
pattern with dispatch('submit', { data })
and handling it with on:submit
event listeners, Svelte 5 enables passing callback functions directly through props <Child onSubmit={handleSubmission} />
. This reduces boilerplate, provides better TypeScript integration, and makes data flow more explicit throughout the application.
<!-- Child.svelte -->
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
function handleSubmit(data) {
dispatch('submit', { data });
}
</script>
<!-- Parent.svelte -->
<Child on:submit={({ detail }) => handleSubmission(detail.data)} />
Svelte 4
<!-- Child.svelte -->
<script>
let { onSubmit } = $props();
function handleSubmit(data) {
onSubmit?.(data);
}
</script>
<!-- Parent.svelte -->
<Child onSubmit={handleSubmission} />
Svelte 5
3. Simplified Prop Handling with $props
Svelte 5's $props
rune brings a cleaner approach to component properties. The verbose export let
syntax from Svelte 4 is replaced with a single destructuring statement let { prop1 = defaultValue, prop2 } = $props()
. This approach significantly reduces code verbosity, improves TypeScript integration, significantly reduces prop-related boilerplate in components, and strengthens type checking.
4. Improved Component Typing
The typing improvements in Svelte 5 have been another standout feature for us. Built-in typed properties like placeholder
and maxlength
now function seamlessly, while custom traits can be defined with precision to ensure type safety. These enhancements have not only reduced the risk of runtime errors but have also made our code more robust and maintainable. Additionally, the deeper integration with TypeScript has significantly improved productivity and reliability.
5. Explicit Reactivity with Runes
Svelte 5's runes system represents a fundamental shift in reactivity management. Instead of Svelte 4's implicit reactivity with let
declarations and $:
statements, Svelte 5 uses explicit runes like $state()
and $derived()
. A typical example shows this evolution:
// Svelte 4
let count = 0;
$: tripled = count * 3;
// Svelte 5
let count = $state(0);
let tripled = $derived(count * 3);
6. Reduced Bundle Sizes
The new compiler in Svelte 5 has brought significant optimisations, leading to bundle size reductions of up to 50% compared to Svelte 4. This efficiency boost not only improves performance but also aligns with our commitment to delivering a lightweight and fast platform.
A Worthwhile?
While adopting Svelte 5 and its new features—like snippets, callbacks, and runes—required some adjustments to our workflow, the results have been well worth the effort. The new features we’ve integrated have allowed us to create a cleaner, more scalable codebase. These changes are already helping us work more efficiently and will undoubtedly lead to fewer bugs and a smoother development experience in the long term.
To stay updated on what’s new at Nomodo, follow us on Twitter or join our Nomodo.io Discord channel. Also, don’t miss exploring MedusaJS.
From all of us at Nomodo.io, thank you for being part of our journey!
Featured ones: