My first Svelte component
Tags: javascript, svelte, beginners, programming
Published: 2022-12-28 18:36:09

---
title: My first Svelte component
description: How to create a reactive Svelte component
tags: javascript, svelte, beginners, programming
published: true
---

In this article, I'd like to explore how to create your first svelte component with a basic Svelte application.
Svelte allows you to create a reactive web application so we will explore the Svelte reactivity.
To do that, we will create a Svelte component that generates a random number (1 to 6), like rolling a dice, and then reactively update the list of all the previous rolls and the result.

> Source code: If you’re in a hurry, have a look at [the code on Github](https://github.com/roberto-butti/roll-the-dice-svelte)

## Install Vite and Svelte skeleton app

For using Svelte with all the tools needed by the building process, I strongly suggest using the Vite tool via `npm create vite@latest` command.
Within the execution of the command, you have to specify 3 things: the new directory of your new project, the framework (Svelte), and the variant (JavaScript or Typescript):

```bash
npm create vite@latest
```

Launching the command without any parameters, during the execution, you have to answer the questions. In the example, we are naming the new directory as `roll-the-dice-svelte`, the Framework as `Svelte` and the variants as `JavaScript':


![Creating Svelte application with Vite](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/png17onnhf7kqzblvo5b.png)

Or, if you are using `npm`, you can define the directory, the framework, and the variant (JavaScript or Typescript) directly in the command line (so the execution of the command is less interactive):

~~~bash
npm create vite@latest roll-the-dice-svelte -- --template svelte
~~~

Then, you can enter into the new directory created by the command and install all the packages:

~~~bash
cd roll-the-dice-svelte
npm i
npm run dev
~~~

Now, you can open your browser at: http://localhost:5173/


![Vite and Svelte basic web application](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/09h85x69lk4v7atwxj0w.png)

## Roll the dice web application

Now I would like to create a very simple “Roll the Dice” web application with Svelte.

The end-user can click a button to generate a random number (from 1 to 6) and update the text where the result is shown and the list of the previous rolls. This example is straightforward but useful for walking through the basic reactivity stuff of Svelte.

So now, let’s jump on the code.

## The Code

The command “npm create vite@latest” created a basic skeleton of the Svelte web application. Now we will focus on two files.

- `src/App.svelte`: where your component is loaded
- `src/lib/RollTheDice.svelte` is the new component file we will create from scratch. In the component, we will define the HTML part and the logic (in the script section with the button, the labels, and the function that generates a random number).

By default, the skeleton Svelte application provides an `src/lib/Counter.svelte` essential component. I suggest you look at this file to understand the structure of a typical Svelte component file. In our example, we will not use the `Counter.svelte` component.

Now, please create a new empty file named `RollTheDice.svelte` in the `src/lib` directory, where we will test and try some basic functionalities of Svelte.


![The Svelte application file structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fhshryt4fwr38jjzjudp.png)

The relevant files for this Svelte application are:

## The `index.html` file

The `index.html` in the root project directory defines the HTML structure with HTML Head and HTML body container, with id `app`, and it includes the js built file `/src/main.js`.
You would probably change the `index.html` to adjust the HTML title in this example.

~~~html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Roll the dice with Vite + Svelte</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

~~~

## The `src/main.js` file

The `main.js` file creates the Svelte App instance and binds the application logic to the HTML element with a specific id.
In this example, we don't have to change this file.

~~~js
### 001 - imports the CSS file (styles)
import './app.css'
### 002 - imports the App.svelte file
import App from './App.svelte'

### 003 - Creates the Svelte app instance
const app = new App({
### 004 - bind the Svelte app instance on the 'app' HTML element
  target: document.getElementById('app'),
})

export default app
~~~

## The `src/App.svelte` file

The main goal of the `App.svelte` file is to load the component.
In the `App.svelte` file in the `<script>` section, you have to import the new component:

~~~js
<script>
  import svelteLogo from './assets/svelte.svg'
  import RollTheDice from './lib/RollTheDice.svelte'
</script>
~~~

In the HTML part, you can use the `<RollTheDice>` tag:

~~~html
<div class="card">
  <RollTheDice />
</div>

~~~

## The new `src/lib/RollTheDice.svelte` file

The component file is slightly longer than the `App.svelte` file.

Let me split it into two parts. The first one is the HTML part, where we will use some variables and functions that we will cover in the script section.

So, two-part: one is the HTML part, and the last one is the script. Both are included in the same file, `RollTheDice.svelte`.

### The template

The first part of the file is for the template:

~~~html
<h1>Number is: {dice}</h1>
<div>Number of rolls: {rolls.length}</div>
<div>Total: {total}</div>
<button on:click={roll}>Let's roll the dice</button>
<button on:click={restart}>Restart</button>

<p>
    { rolls.toString() }
</p>
<div>
    {#each rolls as t, index}
        {#if index == rolls.length -1}
            <b style="background-color: lightgreen;">{t}</b>
        {:else}
            {t} -&nbsp;
        {/if}

    {/each}
</div>

~~~

As you can see, in the HTML part, we are using:

- some variables: `dice`, and the array `rolls` (we are using length attribute);
- a reactive assignment for the reactive variable `total`, where we are calculating the sum of all the values of the `rolls` array;
- a couple of functions called by a user action (click on a button): `roll()` and `restart()`.

### The script

~~~js
<script>
// ##001: declare and initialize two variables dice and rolls
    let dice = 0;
    let rolls = [];
// ##002: declare and define the reactive var total
    $: total = rolls.reduce((t, n) => t + n, 0)
// ##003: declare the roll function
    function roll() {
        dice = Math.floor(Math.random() * Math.floor(5)) + 1
// ##004: instead of using push() method, we are using destructuring and assignment
        rolls = [...rolls, dice]
    }
// ##005: restart() function
    function restart() {
        dice = 0
        rolls = []
    }
</script>

~~~

- ##001: we are declaring and initializing two variables, `dice` and `rolls`.
- ##002: declare and define the reactive variable `total`. We declare reactive variables via `$:` directive because it is a calculated value (like computed properties in Vue).
- ##003: declare the `roll()` function
- ##004: adding an element to the array, generating a new array for making it reactive. Instead of using the `push()` method, we use destructuring and assignment. Otherwise, Svelte doesn't detect the changes in the array (and no reactivity). As the official documentation reports, Svelte's reactivity is triggered by assignments. Methods that mutate arrays or objects will not trigger updates by themselves.
- ##005: declare the `reset()` function.


That’s all for now. So if you have your `npm run dev` already up and running, you have the hot reload functionality provided by Vite so go to your browser, go to `http://localhost:5173/`, and take a look at your new Svelte web application.


![Roll the Dice with your reactive Svelte component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/alulwk43y8gxl2hnueag.gif)

Feel free to leave some feedback in the comment.