DEV Community

Cover image for Intro to Svelte ๐Ÿฆ„โšก๏ธ๐Ÿงก
Sendil Kumar
Sendil Kumar

Posted on • Updated on • Originally published at sendilkumarn.com

Intro to Svelte ๐Ÿฆ„โšก๏ธ๐Ÿงก

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
Enter fullscreen mode Exit fullscreen mode

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

npm i
npm run dev
Enter fullscreen mode Exit fullscreen mode

You should see a simple Hello World application running on localhost:5000.

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.

<script>
        export let name;
</script>

<style>
        h1 {
                color: purple;
        }
</style>
Enter fullscreen mode Exit fullscreen mode

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.

<h1>Hello {name}!</h1>
Enter fullscreen mode Exit fullscreen mode

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

import App from './App.svelte';
Enter fullscreen mode Exit fullscreen mode

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.

const app = new App({
        target: document.body,
        props: {
                name: 'world'
        }
});
Enter fullscreen mode Exit fullscreen mode

Finally, export the app from the main.js.

export default app;
Enter fullscreen mode Exit fullscreen mode

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

import App from './App.svelte';
Enter fullscreen mode Exit fullscreen mode

Want a shorter alternative, fork this codesandbox

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.

<div class="game">
    <Board />
</div>
Enter fullscreen mode Exit fullscreen mode

Now we will need to import the Board component.

<script> 
    import Board from './Board.svelte';
</script>
Enter fullscreen mode Exit fullscreen mode

Let us style the board a little bit.

<style>
.game {
    display: flex;
    flex-direction: row;
}
</style>
Enter fullscreen mode Exit fullscreen mode

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

<div class="board-row">
    <Square />
    <Square />
    <Square />
</div>
<div class="board-row">
    <Square />
    <Square />
    <Square />
</div>
<div class="board-row">
    <Square />
    <Square />
    <Square />
</div>
Enter fullscreen mode Exit fullscreen mode

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

<script>
import Square from './Square.svelte';
</script>
Enter fullscreen mode Exit fullscreen mode

Let us style them a little bit.

<style>
.board-row:after {
    clear: both;
    content: "";
    display: table;
}
</style>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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.

<button class="square" on:click={() => handleClick}> {value} </button>
Enter fullscreen mode Exit fullscreen mode

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

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

function handleClick() {
   value = 'X';
}
Enter fullscreen mode Exit fullscreen mode

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.

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

<button class="square" on:click={handleClick}> {value} </button>
Enter fullscreen mode Exit fullscreen mode

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

<script>
    let squares = Array(9).fill('');
</script>
Enter fullscreen mode Exit fullscreen mode

and change the HTML into

  <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>
Enter fullscreen mode Exit fullscreen mode

We will also need to define the handleClick method.

function handleClick(i) {
    squares[i] = 'X';
}
Enter fullscreen mode Exit fullscreen mode

๐Ÿ‘ 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.

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

function handleClick(i) {
   squares[i] = isXTurn ? 'X' : 'O';
   isXTurn = !isXTurn;
}
Enter fullscreen mode Exit fullscreen mode

Cool, now we have to calculate the winner.

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;
}
Enter fullscreen mode Exit fullscreen mode

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.

function handleClick(i) {
    if (calculateWinner(squares) || squares[i] !== '') {
      return;
    }
   squares[i] = isXTurn ? 'X' : 'O';
   isXTurn = !isXTurn;
}
Enter fullscreen mode Exit fullscreen mode

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.

$: winner = calculateWinner(squares)

$: status =  winner ? "Winner: " + winner :"Next player:" + (xIsNext ? "X" : "O");
Enter fullscreen mode Exit fullscreen mode

We will use the status inside the HTML.


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

<style>
.status {
    margin-bottom: 10px;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

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


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 for even more awesome demos.

Check out more in the docs here.

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

If you like this article, please leave a like or a comment. โค๏ธ

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

You can follow me on Twitter.

Top comments (17)

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
prashanth1k profile image
Prashanth Krishnamurthy

The classification of the frameworks in this way may be easy today, but we should also be talking about what Svelte does differently and how it affects web dev in the long term? As browsers become much better in what they do - maybe, just maybe, every framework must have a part of Svelte built into them (more specifically the DOM updates, similar to Ivy in Angular). See reddit.com/r/javascript/comments/c... for a live discussion where a number of framework creators have jumped in to add their view-point on vdom vs dom updates.

If I have to choose a framework today and I am a beginner/intermediate developer: I would certainly go towards Vue or React. Larger community = more help. If I have to choose one of them - I would choose one that I personally like (Vue) or the one that my team is comfortable working in. I don't build Facebook-level apps, but from what I have seen Vue is good for me in building a scalable enterprise-grade, JS-heavy app as React.

I will incorporate Svelte in some future work. I still am not sure how Svelte can manage DOM updates under a high workload - but do not see that as a technical limitation that makes it suitable only for a "light app or blog".

Cheers.

Collapse
 
adam_cyclones profile image
Adam Crockett ๐ŸŒ€

Angular is suitable for? ๐Ÿ˜…

Collapse
 
jappyjan profile image
jappyjan

... being deprecated ๐Ÿ˜…
... Slow applications
... Bloated applications
... Legacy applications

Thread Thread
 
adam_cyclones profile image
Adam Crockett ๐ŸŒ€ • Edited

Architecture in angular is admittedly beautiful, but I'm moving away from Oop. I think the decipline in writing an Angular app is what it's good for and a lesson for future frameworks. It's easy to hate on angular and I am not a fan to be clear.

Collapse
 
highcenburg profile image
Vicente G. Reyes

Hi, I removed the #beginners tag. The tag should be for devs on the 0-2/10 scale. You can check the updated guidelines for the tag here :

Collapse
 
sendilkumarn profile image
Sendil Kumar

This is interesting, I still believe this is a beginner post. But I respect the decision. Thanks for letting me know

Collapse
 
highcenburg profile image
Vicente G. Reyes

This is a framework which is learned after the beginner stage. Thanks for understanding.

Collapse
 
v0idifier profile image
void

you said that HTML is required but it actually isn't. a component can be an empty file

Collapse
 
joeberetta profile image
Joe Beretta
Collapse
 
joeberetta profile image
Joe Beretta

Love this "getting started" tutorial. I heard about Svelte some months ago but couldn't start learn it. Think I'll do it in my next side project

Collapse
 
thgh profile image
Thomas Ghysels

Typo: the first on:click={() => handleClick} should be without arrow function

Collapse
 
robbsadler profile image
RobbSadler

Helpful article.

Something I would love to see is instruction on where to put static elements like images. I have been successful in putting them directly in the build output folder, but is this the correct practice? I would think they would go in the src folder and be part of the compile. But I have not been able to get the compiler to include static files. Is there a compiler directive to make this happen?

I even pulled a REPL of the svelte example that uses and references a static image and found that the image was not included in the download :). Such a simple thing, but I don't see it addressed in the docs (probably not looking in the right place).

Thanks!

Collapse
 
robbsadler profile image
RobbSadler

OK, I think I see now - really a noob w/ svelte - The static stuff goes in public, and the built stuff gets put in build. That makes sense. Did I get that right?

Collapse
 
leastbad profile image
leastbad

It's great to see more frameworks and tools eschew the assumption that a virtual DOM is an automatic improvement.

However, in this example, I honestly don't understand why you wouldn't just use StimulusJS. Further, the claim that a Svelte template is just HTML is demonstrably inaccurate; after all, if that were the case, you wouldn't need to pre-process them.

Most of the people evaluating Svelte would be better served by Stimulus. It's powering some of the most powerful sites on the web, and the people behind it are the same folks that do Rails and Turbolinks. #winning

stimulusjs.org/

Collapse
 
adam_cyclones profile image
Adam Crockett ๐ŸŒ€

I like that svelte harps back to the days pre angular 1. I am most interested in the compiler, does it parse and lex ES6 and how hard is that to create?

Collapse
 
codercatdev profile image
Alex Patterson

I am really digging learning more about Svelte! Here is a video tutorial using Firebase as backend.
ajonp.com/lessons/rxfire-in-svelte...