Intro to Svelte 🦄⚡️🧡
Tags: javascript, webdev, svelte
Published: 2019-08-04 15:10:34

# Why yet another framework to learn? 🤦‍♂️🤦‍♀️

> If you are worried about tons of front-end frameworks and their variations out there, why yet another framework?

The frameworks like Angular, ReactJS or VueJS make it easier, faster to spin up applications. More robust and efficient application development within a team. 

They changed the way in which we design, develop, and deliver the applications. 

More and more frameworks refine the frameworks and make it, even more, easier to develop simple, fast, and efficient applications.

**Angular** ❤️

Angular is a complete suite but it is bloated.

**React** 💙

React is a `view only` library and uses `virtual DOM` but React gets complicated.

**Vue** 💚

VueJS is a simple to write and has the best parts of React and Angular. 

**Svelte** 🧡

Svelte is a new approach to build user interfaces. The Svelte has no virtual DOM. 

Svelte makes you write less code and `uses the platform`. 

Svelte has no virtual DOM and `uses the platform`. 

Svelte optimizes the application during the build process that increases your application's performance.

# Get the app and start running

Enough of (boring) framework introductions, let us start coding.

_Where to start?_ 

"Hello World"

```
npx degit sveltejs/template hello-world
cd hello-world
```

You have cloned a template from the `sveltejs/template`. Now install the dependencies and spin the server using

```
npm i
npm run dev
```

You should see a simple `Hello World` application running on [localhost:5000](http://localhost:5000).

![](https://thepracticaldev.s3.amazonaws.com/i/21gxwk0tva19m4awtm8p.png)

Let us dive deeper and look at what is generated.

The `Svelte` components are defined in `.svelte` files. The generated application has the `App.svelte`.

The `Svelte` components are nothing but a simple `HTML` file. All Svelte components can have the following three segments:

* Script - to define the JavaScript
* Style - to define the CSS
* plain HTML - just your HTML and Svelte elements


If you have worked with any frameworks listed above then you might know what are `props`. 

> `Props` are attributes that you pass it along the `Components`.

The `export let name` inside the `script` tag says that the `name` is exported from the component and we can send it the information via the attributes.

The `props` attached to your components will be first `exported` out of the component.

```html
<script>
        export let name;
</script>

<style>
        h1 {
                color: purple;
        }
</style>
```

Any variable (including the props) that we defined inside the `<script>` component can be used in the `HTML component` with `{variable_name}` notation. The `{}` is used to define the value defined in the `script` tag.

```html
<h1>Hello {name}!</h1>
```

The application starts in the `main.js`. We import the `App.svelte` (where the `App` component is defined).

```javascript
import App from './App.svelte';
```

Then we create an App object from the imported `App` component. Then we define `target` and also pass in `props` to the component's constructor.

The `target` defines where to render the component in the HTML document.

The `props` is the place where we will define the attributes.

```javascript
const app = new App({
        target: document.body,
        props: {
                name: 'world'
        }
});
```

Finally, export the `app` from the `main.js`.

```javascript
export default app;
```

There is the `rollup.config.js` which takes care of bundling and building the application. 

```javascript
import App from './App.svelte';
```

Want a shorter alternative, fork this `codesandbox`

{% codesandbox magical-gates-vfhbg %}

# Tic Tac Toe

Let us re-create the classic `Tic Tac Toe` from the react (official) example with `Svelte`.

Create a components folder, this is where we will define all the `Svelte` components except the `App.svelte`. 

We will need the following components:

* `Square.svelte` - Each square in the Tic Tac Toe will be a separate `svelte` component.
* `Board.svelte` - The Board component will hold all the square components. This component will be responsible for passing the data to its child `square` components and also decide whether the game is still on or finished.
* `Game.svelte` - The Game component is an overall wrapper around the `Board` component.


Let us first create `Game.svelte` component. The Game Component will hold the `Board` component. 

```html
<div class="game">
    <Board />
</div>
```

Now we will need to import the `Board` component.

```html
<script> 
    import Board from './Board.svelte';
</script>
```

Let us style the board a little bit.

```html
<style>
.game {
    display: flex;
    flex-direction: row;
}
</style>
```

---

The Board component will have three rows of three squares in each.

```html
<div class="board-row">
    <Square />
    <Square />
    <Square />
</div>
<div class="board-row">
    <Square />
    <Square />
    <Square />
</div>
<div class="board-row">
    <Square />
    <Square />
    <Square />
</div>
```

We will need to import the `Square` component in the `<script>` section.

```html
<script>
import Square from './Square.svelte';
</script>
```

Let us style them a little bit.

```html
<style>
.board-row:after {
    clear: both;
    content: "";
    display: table;
}
</style>
```

---

Then we will define the `Square` component inside the `Square.svelte`.

```
<style>
 .square {
    background: #fff;
    border: 1px solid #999;
    float: left;
    font-size: 24px;
    font-weight: bold;
    line-height: 34px;
    height: 34px;
    margin-right: -1px;
    margin-top: -1px;
    padding: 0;
    text-align: center;
    width: 34px;
  }

 .square:focus {
    outline: none;
 }

 .square:focus {
    background: #ddd;
 }
</style>

<script>
let value = "";
</script>

<button class="square"> {value} </button>
```

We defined `value` and used that inside the `button` element.

When we click the button it should change the value into `X`. We will use the `on:click` event handler.

```html
<button class="square" on:click={() => handleClick}> {value} </button>
```

The event handler in `Svelte` is defined `on:<event>`. 

Let us define the `handleClick` inside the `<script>` tag.

```html
function handleClick() {
   value = 'X';
}
```

Now click on the button, you should see the value of button is changed into `X`.

> There is no `this`, no complex bindings but a simple variable declaration and changing it.

---

It is not easy to maintain the state in the child component and then propagating it to the parent. Rather we can move the state to the parent and then make the parent decide on how to maintain the child component. To do this, let us change the `Board` component and send the `value` and the `on:click` event handler through the `Board` component.

Let us consider both the `on:click` and `value` is a `prop` to the `Square` component.

```html
<script> 
export let value; 
export let handleClick;
</script>

<button class="square" on:click={handleClick}> {value} </button>
```

Now we will modify the `Board` component. Instead of defining each `Board` we will define an array `squares` and use it.

```html
<script>
    let squares = Array(9).fill('');
</script>
```
and change the HTML into

```html
  <div class="board-row">
    <Square value={squares[0]} handleClick={() => handleClick(0)}/>
    <Square value={squares[1]} handleClick={() => handleClick(1)}/>
    <Square value={squares[2]} handleClick={() => handleClick(2)}/>
  </div>

  <div class="board-row">
    <Square value={squares[3]} handleClick={() => handleClick(3)} />
    <Square value={squares[4]} handleClick={() => handleClick(4)} />
    <Square value={squares[5]} handleClick={() => handleClick(5)} />
  </div>


  <div class="board-row">
    <Square value={squares[6]} handleClick={() => handleClick(6)} />
    <Square value={squares[7]} handleClick={() => handleClick(7)} />
    <Square value={squares[8]} handleClick={() => handleClick(8)} />
  </div>
```


We will also need to define the `handleClick` method.

```javascript
function handleClick(i) {
    squares[i] = 'X';
}
```

:clap: Congrats that is awesome. Let us build the real game.

---

The Game is played alternatively, that is one player marks with `X` and the other with `O`. Let us add that condition in the `Board` component.

```html
<!-- Board.svelte -->
let isXTurn = true;

function handleClick(i) {
   squares[i] = isXTurn ? 'X' : 'O';
   isXTurn = !isXTurn;
}
```

Cool, now we have to calculate the winner. 

```javascript
function calculateWinner(squares) {
    const lines = [
      [0, 1, 2],
      [3, 4, 5],
      [6, 7, 8],
      [0, 3, 6],
      [1, 4, 7],
      [2, 5, 8],
      [0, 4, 8],
      [2, 4, 6]
    ];
    for (let i = 0; i < lines.length; i++) {
      const [a, b, c] = lines[i];
      if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
        return squares[a];
      }
    }
    return null;
}
```

The above function will return `X` or `O` if there is a winner or else just returns a `null`.

We will have to check this every time when the user clicks the square. Also once a player clicks a square we should not allow any other clicks on that square.

```javascript
function handleClick(i) {
    if (calculateWinner(squares) || squares[i] !== '') {
      return;
    }
   squares[i] = isXTurn ? 'X' : 'O';
   isXTurn = !isXTurn;
}
```
---

We will need to show the game status for the players. The game status information is dynamic. That is it will change and there should be someone listen to it and change the view once updated. 

In React world we will have the `state`. In Svelte we bind the components with `$`. The values will be updated.

```javascript
$: winner = calculateWinner(squares)

$: status =  winner ? "Winner: " + winner :"Next player:" + (xIsNext ? "X" : "O");
```

We will use the status inside the `HTML`.

```html

 <div class="status"> {status} </div>

<style>
.status {
    margin-bottom: 10px;
  }
</style>
```

Now the status is re-computed whenever there is a change.

{% codesandbox heuristic-spence-bvzun %}

---

The Svelte components are slim, no extra boilerplates, no `this` and it is much closer to the platform. In fact, they are nothing but simple `HTML`.

Check out [Svelte example sites](https://svelte.dev/examples) for even more awesome demos. 

Check out more in the docs [here](https://svelte.dev/docs).

We will continue with even more in-depth tutorial about `Svelte`.

If you like this article, please leave a like or a comment. :heart:

If you feel there is something wrong / missing in the article feel free to comment :) 

You can follow me on [Twitter](https://twitter.com/sendilkumarn).