SVAR Blog Svelte

Release of SVAR Svelte v.2.0 Beta: How We Migrated to Svelte 5

Maksim Kozhukh

Nov 27 · 6 min read

Release of SVAR Svelte v.2.0 Beta: How We Migrated to Svelte 5

The recent release of Svelte 5 brings significant changes to the framework. It promises better performance, cleaner code, easier debugging, and more efficient compiled output for smaller bundles and faster apps.

Try SVAR 2.0 Beta for Svelte 5

First things first: we’re introducing the release of Svelte 5-compatible versions of our SVAR Svelte components. All the components receive version number 2.0.0 beta. Since it’s still a beta release, it might contain some rough edges, but we’re excited to hear your feedback!

NOTE: Version 2.0 beta is now the default when you install the SVAR components via npm. Or you can add @2.0.0-beta-x to the installation:

SVAR Core Components:

npm install wx-svelte-core@2.0.0-beta-2
npm install wx-svelte-menu@2.0.0-beta-2
npm install wx-svelte-toolbar@2.0.0-beta-2
npm install wx-svelte-uploader@2.0.0-beta-2

Advanced SVAR Widgets:

npm install wx-svelte-grid@2.0.0-beta-3
npm install wx-svelte-gantt@2.0.0-beta-3
npm install wx-svelte-filemanager@2.0.0-beta-3

If you find any bugs or have suggestions for improvements, please submit an issue to the relevant repository on GitHub. Together, we can make these components even better!

What’s New in Version 2.0 Beta

Not much has changed in how the components are used, which is good news. SVAR Svelte components and their properties remain largely the same. However, there are two notable differences:

Updated Event Handling Syntax

Svelte 5 deprecates the old syntax for event handling, and the same applies to our components. In previous versions, events were bound using the on: syntax, like:

<Text on:change={handler} />

In Svelte 5, this has transitioned to a more straightforward approach:

<Text onchange={some} />

Changes to DataGrid, Gantt, and File Manager APIs

The second major update is related to our Svelte DataGrid, Gantt, and File Manager components. Previously, you were able to get their APIs like this:

<Grid bind:api={api} />

This approach is discouraged in Svelte 5, and now you need to use the bind:this construct. For example:

<Grid bind:this={api} />

Changes Under the Hood

Our upgrade of SVAR components to the latest Svelte version has been an exciting journey. While the migration process has been mostly straightforward, some changes, e.g. converting reactive blocks to $derived and $effect runes, required serious thought and occasionally redesigning small parts of the components to better suit the new approach.

New Syntax for Slots

Slots in Svelte 5 use a different syntax, and while you can theoretically continue using the older Svelte syntax in backward compatibility mode, the latest version of the framework breaks when it encounters $$props usage, which was necessary for optional slots. Rewriting this part was straightforward, and the new syntax retains all the previous functionality.

From:

{#if $$props.$$slots.default}<slot />{/if}

To:

{#if children}{@render children()}{/if}

On the other hand, providing custom parameters for slots has become more verbose:

From:

<Combo let:option={option}>{option.name}</Combo>

To:

<Combo>
{#snippet children({ option })}
{option.name}
{/snippet}
</Combo>

The need for an extra #snippet section is a small price to pay for cleaner code.

New Event Syntax

createEventDispatcher and custom events are deprecated in favor of callback parameters. I’m not sure how I feel about this one. I never liked the need to create a dispatcher for triggering an event, nor the cumbersome process of unpacking data from the details property. The new approach, using callbacks, pleases my desire for simplicity. Still, I feel a bit sad, because there was something beautiful about sending events instead of triggering callbacks.

As a result, a lot of changes were made, replacing code like:

const dispatch = createEventDispatcher();
dispatch('onchange', { value });

With:

onchange && onchange({ value });

And, of course, all instances of ev.detail were eradicated.

Reactivity Overhaul — Embracing $effect and $derived

This was the trickiest part. Svelte 5 deprecates the $: reactive blocks and suggests that code should use $effect for post-render operations and $derived for dependent computations. There is a catch though: $effect must not have side effects, so any changes in the state are not allowed.

In theory, it simplifies the mental model (yes), improves readability (definitely), and preserves the elegance of reactive programming (somewhat).

Unfortunately, our reactive blocks were not very elegant, so it took some time to untangle that complexity. It was rewarding work, though—the resulting code is much easier to understand. There are some rough edges, for example, the $derived rune that returns an object will not recalculate itself if a property of the object changes but the object itself remains the same.

On the positive side, the new syntax works with classic Svelte stores, which simplified our struggle significantly. We embraced the new state management for view logic while preserving the classic store-based approach for interacting between the UI and model layers.

Are the Results Impressive?

Mostly, yes. The updated code is cleaner, easier to read, and hopefully more maintainable.

One of the highlights of Svelte 5 is its ability to produce smaller bundles. For instance, After migrating our SVAR Core components, we observed a dramatic reduction in bundle size—from 280 KB to just 155 KB. Other widgets also show a significant decrease in the size of the final bundles.

We also expect performance improvements, although these have not been thoroughly tested yet.

What’s Next?

We plan to battle-test the beta packages and, based on the outcome, make some improvements to functionality. We plan to release the final version of Svelte 5-compatible components in two weeks along with updated documentation.

Version 1.x for Svelte 4

As for the Svelte 4 compatible version, it will remain on npm and may see some bug fixes (as we are still using it for our other projects), though no major functionality will be added. You can install v.1.x of the SVAR components like this:

SVAR Core Components:

npm install wx-svelte-core@1.3.0
npm install wx-svelte-menu@1.3.0
npm install wx-svelte-toolbar@1.3.0
npm install wx-svelte-uploader@1.3.0

Advanced SVAR Widgets:

npm install wx-svelte-grid@1.3.0
npm install wx-svelte-gantt@1.2.0
npm install wx-svelte-filemanager@1.3.0

Stay Tuned!

Svelte 5 compatibility marks an exciting new chapter for SVAR components, with improved performance, modern syntax, and a more enjoyable development experience. We can’t wait to see what you build with it.

Keep an eye on our GitHub and follow us on social media for updates. There’s plenty more to come as we continue refining and enhancing SVAR components!

Happy coding!