What's New in Svelte 4: Performance Boosts and Streamlined Development
Tags: svelte, webdev, javascript, news
Published: 2023-06-25 08:26:23

On the 22th of June, [Svelte](https://svelte.dev) has [announced its new major release](https://svelte.dev/blog/svelte-4).

Even if it is presented as "mainly about setting the ground for these future improvements", it also bring its share of improvements along with the rework of some of their showcase websites.

> If you're more a listener than a reader, this release has also been recorded on [Svelte Radio Live](https://www.youtube.com/watch?v=72TIVhRtyWE)

## Table of Content

- [Performance Enhancements](#performance-enhancements)
- [Improved Developer Experience](#improved-developer-experience)
- [Updated Websites](#updated-websites)
- [Migration Guide](#migration-guide)
- [What to Expect From Svelte 5](#what-to-expect-from-svelte-5)

---

## Performance Enhancements

### 📉 Drastic reduction of the Svelte package

For this release, Svelte sure has lost some weight!

The overall size of Svelte dropped **from 10.6 MB to 2.8MB**, almost a 75% size decrease.

As its dependencies dropped **from 61 to 16**, the additional packages needed to run Svelte also have been reduced, also reducing the number of dependencies of SvelteKit.

This reduction brings some nice side effects such as a faster REPL experience, a faster experience on the interactive website and a much faster execution of `npm install` (of whatever package manager you might be using).

As of this release, Svelte sure is now!

### 🚿 Improved Hydration

Along with this drop in the package size, Svelte also lighten the code it generates for hydration.

As an example, the code generated for [the SvelteKit website](https://kit.svelte.dev/) has been reduced from 126.3 kB to 110.2 kB, almost 13%.

## Improved Developer Experience

### 🎭 Transitions Scope

Transitions are now local by default.

This prevents them from being global by default and thus risking to interfere with others, resulting in a collision of your transitions during page load.

### 🧱 Web Components Authoring

Creating a Web Component in Svelte has been pretty easy:

```html
<svelte:options tag="my-component" />
```

However it also has been limiting for more advanced cases such as controlling whether or not to reflect updated prop values back to the DOM, disabling the shadow DOM, etc.

Svelte 4 makes the authoring experience of Web Component way smoother by shifting its configuration into a dedicated `customElement` attribute of `svelte:options`.

This attribute takes [a number of options](https://svelte.dev/docs/custom-elements-api#component-options) that helps you configure your Web Component:

```html
<svelte:options
  customElement={{
    tag: 'custom-element',
    shadow: 'none',
    props: {
      name: {
        <!-- 👇 Reflects the updated value back to the DOM -->
        reflect: true,
        <!-- 👇 Reflects the value as a number -->
        type: 'Number',
        <!-- 👇 Name of the attribute -->
        attribute: 'element-index'
      }
    }
  }}
/>

<script>
  export let elementIndex;
</script>

...
```

### 🛡️ Stricter Types

Stricter types are now [enforced for `createEventDispatcher`, `Action`, `ActionReturn` and `onMount`](https://svelte.dev/docs/v4-migration-guide#stricter-types-for-svelte-functions):

- `createEventDispatcher` now looks for the correctness of the provided parameters regarding their type and number and throws the associated errors:

```js
import { createEventDispatcher } from 'svelte';
 
const dispatch = createEventDispatcher<{
  optional: number | null;
  required: string;
  noArgument: never;
}>();
 
// Svelte version 3:
dispatch('optional');
dispatch('required'); // Detail argument still omitted
dispatch('noArgument', 'surprise'); // Detail argument still provided
 
// Svelte version 4 using TypeScript strict mode:
dispatch('optional');
dispatch('required'); // Error, missing argument
dispatch('noArgument', 'surprise'); // Error, cannot pass an argument
```

- `Action` and `ActionReturn` now have a default parameter type of `never` if `Action` has no generic type provided:

```ts
const untyped: Action = (node, params) => {
  // Now an error as `params` is expected not to exist
}

const typed: Action<HTMLElement, string> = (node, params) => {
  // `params` is of type string
}
```

- `onMount` now requires its return a synchronous function as an asynchronous one might lead to bugs if the callback is expected to be called on destroy, since this is the case only for synchronous functions:

```ts
// ❌ `cleanup()` is not called due to the function being async
onMount(async () => {
  const bar = await foo();
  return cleanup();
});

// ✅ `cleanup()` will be called
onMount(() => {
  foo().then(bar => /* ... */ );
  return cleanup();
});
```

## Updated Websites

### 📝 Tutorial Website

[The tutorial](https://learn.svelte.dev) has been reworked for a better user experience:

| Former | Newer |
|:------:|:-----:|
| ![Legacy Tutorial](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4d190xqnii4ggjllrad2.png) | ![Newer Tutorial](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pq17czculsivklzvlhr3.png) |

The design still is the same: a side panel with text and instructions with a code editor on the right to do the exercise.

However, some neat things were improved such as seeing the file structure on the side, reducing the number of elements in the navbar and a better navigation between sections. It also feature a  dark mode!

The tutorial now lives on [https://learn.svelte.dev](https://learn.svelte.dev) while the former is reachable at [https://svelte.dev/tutorial/basics](https://svelte.dev/tutorial/basics)

### 📚 Svelte Website

The [Svelte Website](https://svelte.dev) also had a rework:

| Former | Newer |
|:------:|:-----:|
| ![Legacy Page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zc0aswjuu2o5evzbsqea.png) | ![Newer Page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7drkdmdaftcj74t0eiab.png) |

The pages have been split, mobile navigation has been improved, the TypeScript documentation has been enhanced and a dark mode has also been released.

As of now, the [SvelteKit](https://kit.svelte.dev/) website has not yet been updated but a rework to offer a similar experience is currently ongoing.

## Migration Guide

This release is shown as a step towards Svelte 5 and not a very impactful one.

In order to upgrade from Svelte 3 to Svelte 4, the team has updated their migration tool and it should not take much more than running the following command:

```shell
npx svelte-migrate@latest svelte-4
```

Please note that the minimum version requirements have been updated and you will need:

- NodeJS 16 or higher
- SvelteKit 1.20.4 or higher
- TypeScript 5 or higher

More details about the requirements are listed in the [migration guide](https://svelte.dev/docs/v4-migration-guide#minimum-version-requirements)

## What to Expect From Svelte 5

Almost no information about what is upcoming in Svelte 5 has been shared so far.

However, as Svelte is heavily tied to ESLint, so is its package size. With the current [rewrite of ESLint](https://github.com/eslint/eslint/discussions/16557), by the time Svelte 5 is released, its size might drop by over another 50%.

As Svelte is focused on developer experience and efficiency, the changes we will probably see a number of improvements in those areas, as stated in their [blog post](https://svelte.dev/blog/svelte-4):

> Svelte 5 will bring major new features and performance improvements to Svelte

---

I hope that you learn something useful there!

{% embed https://dev.to/pbouillon %}