DEV Community

Cover image for My first Svelte5 reactive component
Roberto B.
Roberto B.

Posted on • Updated on

My first Svelte5 reactive component

Welcome to the exciting era of Svelte 5!
After an intensive development period, Svelte 5 has emerged in its Release Candidate (next) version, marking a significant milestone for the Svelte community.
Developers now have the opportunity to explore the cutting-edge features and enhancements introduced in this latest iteration with the Release Candidate.

It's important to note that while Svelte 5 is available for experimentation, it is not recommended for production use at this stage. Several aspects, such as the installer, are still being refined and finalized. As of today, with the release of the "next" version, the installer is not yet available, emphasizing the ongoing nature of development.

We'll explore how you can start exploring the powerful new features, including the revamped and potent reactivity mechanism, installing Svelte 5 on your local development environment.

Install the Svelte 5 skeleton project

Because today the Svelte 5 is not yet completed, we are going to install the skeleton project with the current version of Svelte the 4 (latest), and then once the project is created, we will force the upgrade of Svelte 5 (next)

bun create svelte@latest  myapp-svelte5
cd myapp-svelte5
bun install
Enter fullscreen mode Exit fullscreen mode

If you prefer using npm instead of bun, you can use the npm create and the npm install commands.

During the execution of bun create svelte@latest, the command will ask you some questions. For now, you can answer in this way:

◇  Which Svelte app template?
│  Skeleton project
│
◇  Add type checking with TypeScript?
│  Yes, using JavaScript with JSDoc comments
│
◇  Select additional options (use arrow keys/space bar)
│  Try the Svelte 5 preview (unstable!)
Enter fullscreen mode Exit fullscreen mode

After you jump into the new directory project and install all the packages, if you are using Svelte 4, you need to force the reinstallation of svelte, the next version. Today next refers to the Svelte 5 preview version. If you selected Try the Svelte 5 preview (unstable!) during the project creation, you don't need these steps:

bun add svelte@next 
Enter fullscreen mode Exit fullscreen mode

If you prefer to use npm:

npm i svelte@next 
Enter fullscreen mode Exit fullscreen mode

If you run the command bun pm ls (or npm list if you prefer npm), you can see the version of the svelte package (at the moment, it is svelte@5.0.0-next.115):

bun pm ls
/Users/roberto/test/myapp-svelte5 node_modules (209)
├── @sveltejs/adapter-auto@3.2.0
├── @sveltejs/kit@2.5.7
├── @sveltejs/vite-plugin-svelte@3.1.0
├── svelte@5.0.0-next.115
├── svelte-check@3.7.0
├── typescript@5.4.5
└── vite@5.2.10
Enter fullscreen mode Exit fullscreen mode

Now, if you run bun run dev, you can start using your new fresh Svelte 5 application, typically exposed by default at http://localhost:5173/ .

Now, we are going to create a new component with some reactivity.

Roll the dice web application

I want to create a simple “Roll the Dice” web application.

The user can click a button to generate a random number (from 1 to 6) and update the text showing the result and the list of the previous rolls.
This example is elementary but helpful in walking through the basic stuff of Svelte 5, understanding the main differences with Svelte4, and looking at the new Svelte5 reactivity mechanism via runes.

So now let’s jump on the code 🚀.

Creating the component

I will create the roller.svelte component in the file src/lib/components/roller.svelte.
The component will contain two classical parts: the first one about the logic (the script section), and then the second one about the template (the HTML part).

The script section:

<script>
    /** @type {number} */
    let dice = $state(0);
    /** @type {Array.<number>} */
    let rolls = $state([]);

    function draw() {
        dice = Math.floor(Math.random() * Math.floor(5)) + 1;
        rolls[rolls.length] = dice;
    }
    function reset() {
        dice = 0;
        rolls = [];
    }
</script>
Enter fullscreen mode Exit fullscreen mode

I defined two reactive variables via the $state() function.
Then, I implemented two functions, draw() and reset(), that act directly on the new variables dice and rolls.

In the template part of the svelte component, you can use the variables and call the functions:

<section style="padding-top: 50px;">
    <button onclick={draw}> Let's draw </button>
    <button onclick={reset}> Let's restart </button>
</section>
<section>
    <h2 style="text-align: center">
        {dice == 0 ? "Let's start rolling" : dice}
    </h2>

    {#each rolls as t, index}
        <p style="text-align: center">
            Rolling number {index + 1}, the dice says {t}
        </p>
    {/each}
</section>
Enter fullscreen mode Exit fullscreen mode

The first button calls the draw() function on the click event.
The second button calls the reset() function on the click event.
In the template, I can use the 2 "state" variables, dice and rolls in the typical Svelte way (with #each directive for looping the rolls array).

Highlight on variable declaration

As you can see above, the only thing that I needed to do was to declare the variables I wanted to be reactive with the $state() function:

/** @type {number} */
let dice = $state(0);
/** @type {Array.<number>} */
let rolls = $state([]);
Enter fullscreen mode Exit fullscreen mode

Using the new component

In the src/routes/+page.svelte file, I can use the new Svelte component:

<script>
    import Roller from "$lib/components/roller.svelte";
</script>

<main class="container">
    <Roller />
</main>
Enter fullscreen mode Exit fullscreen mode

Providing the style

For this quick example, I used the PicoCSS library, so in the src/app.html, you need to include it in your head section:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@1/css/pico.min.css">
Enter fullscreen mode Exit fullscreen mode

The Svelte5 component using the reactivity

Are you playing with the new Svelte 5?

I wrote this small article riding the excitement for the new announcement by Rich Harris on November 11th about Svelte 5 BETA:

And the announcement of Svelte 5 RC:

Please feel free to share your thoughts in the comments section below if you have any feedback. I appreciate your input and value the community's insights. I am committed to keeping this article up-to-date with the latest developments in Svelte 5, so your contributions will be significant in ensuring it's accurate and relevant. Thank you for being part of this journey, and I look forward to exploring the exciting advancements that Svelte 5 has to offer together. Stay tuned for future updates!

Top comments (4)

Collapse
 
mfp22 profile image
Mike Pearson

dice could be downstream from rolls

This is how I'd do it in the next version of StateAdapt

const { draw, reset, $state: rolls } = adapt([0], {
  draw: state => [...state, (math random stuff)],
})
const dice = $derived(rolls[rolls.length - 1]);
Enter fullscreen mode Exit fullscreen mode

Just an idea. Probably on dangerous ground with the $state keyword. But it works

Collapse
 
robertobutti profile image
Roberto B.

Thank you for the feedback.
Managing arrays as a state is something that I'm exploring more in order to identify the "best way" to manage them.
For example, i want to replace adding item into an array with :

rolls = [...rolls, dice]
Enter fullscreen mode Exit fullscreen mode

I will monitor the side effects.
I want to explore more "Fine grained reactivity" https://www.youtube.com/watch?v=gGwnF-lxS_Q&t=313s

Collapse
 
mfp22 profile image
Mike Pearson

For my own future reference svelte-5-preview.vercel.app/#H4sIA...

Collapse
 
juanfrank77 profile image
Juan F Gonzalez

That's good stuff. Congrats. 👏