What is Svelte?

I think I might have attention-deficit disorder (ADD) when it comes to technology. Part of the fun of code is discovering new concepts, new frameworks. All the exciting stuff that someone has created and that works in new and fascinating ways. I love learning new things.

That being said, I've never been attracted to learning Vue.js. Why? Because I already use React and Angular. Vue.js feels like a cousin from the same family. I might not know it, but I haven't seen anything in there that has sparked my curiosity.

Svelte, on the other hand, is a whole new kettle of fish. At first glance, it uses completely different concepts, and that makes me want to understand how they work. And with a bit of luck, also help other people understand.

I learn by doing, so I usually start by installing. Then I look at the examples, tinker about, and try to understand what is going on. If I'm really struggling, I'll read the docs. So I installed Svelte (and Sveltekit), tried the basic examples, changed a few things here and there, and…it was a huge failure. I couldn't understand how the state worked, how it updated itself. So I read the documentation and the tutorial and tried to understand what Svelte is. Here is what I discovered

What is Svelte?

According to the landing page, Svelte doesn't use a virtual DOM, but "compiles components into vanilla Javascript”. Unlike React or Vue which embed the framework in the page. What does this mean?

Svelte has no explicit state management

It took me a while to figure out what it meant and to understand what the underlying principles are. There's no explicit setState in Svelte, no place to report that "this is a state”, only a simple:

<script>
let counter = 1;
</script>

And I thought that this would end up aslet counter = 1 somewhere in the output. But the real output is stranger and much more interesting.

At one point while reading the documents and videos, I had an "Aha moment”, complete with angels choirs signing and rays of light shining down from heaven. And yet everything had already been stated in the sentence "Svelte compiles the components”. Truth be told, Svelte is not a framework. At least not primarily, not in the sense that we use it for Vue and Angular and React.

Above all else, Svelte is a compiler.

And this compiler cheats. It does so very cleverly, of course. But it gave me the impression that I was coding in JavaScript, and that was simply not true.

The Svelte compiler cheats

Svelte cheats by overloading the = operator, by adding side effects to it. It adds a function, which updates the variable wherever it is used. In the same way, Svelte parses the HTML, at build time, to find dependencies to this variable.

And this is where the absence of virtual DOM comes into play. React keeps the state and the component tree in memory. And stores the component CSS classes, and style, and the values of its attributes. At the next frame, it compares all the parameters (style, classes, properties, etc.) and if even one has changed slightly, all the child components that depend on it need to be recalculated. Every iteration the engine compares all the elements of the components tree, one to one. And this can end up being expensive.

On the other hand, Svelte just plugs the variable directly into the HTML by overloading the = assignment operator.

Svelte and observable dependencies

And Svelte goes further, by also overloading an underused yet valid JavaScript feature (the JS label), to create dependencies between variables. The label uses "$”, harking back to observables. Let's have a look at the Svelte example:

    <script>

<!---->

    let firstName = 'world';
    let greeting;

<!---->

    $: greeting = 'Hello ' + firstName;
    firstName = 'Bob';

<!---->

    </script>

<!---->

    <h1> {greeting}!</h1>

If we were to run the script section using vanilla JS and log the final value of the greeting variable, we'd see that it contains "Hello world” since the second assignment on firstName ("Bob”) occurs after the greeting variable's assignment.

But in this example, Svelte outputs "Hello Bob”, as if the connexion between the greeting and firstName variables is not just a fleeting relationship but a lasting one. A wedding instead of a one-night stand.

If we log what's going on, we get a clearer picture.

    <script>

<!---->

    let firstName = 'world';
    let greeting;
    $: greeting = 'Hello ' + firstName;
    firstName = 'Bob';
    console.log(greeting);

<!---->

    </script>

<!---->

    <h1> {greeting}!</h1>

This outputs an undefined in the console — the code at the $ label hasn't been called yet when we reach the log. But the label syntax has an interesting feature: you can put a block of code in there. Let's add do so and add a log:

    <script>

<!---->

    let firstName = 'world';
    let greeting

<!---->

    $: {
      greeting = 'Hello ' + firstName;
      console.log(greeting);
    }

<!---->

    firstName = 'Bob';
    console.log(greeting);

<!---->

    </script>

<!---->

    <h1> {greeting}!</h1>

And in this case, the console printout reads "undefined”, then "Hello Bob”. So the label is called once the script block has been executed.

Now, we can actually put several labeled blocks in there. What happens if we mess up the order, and log the value of the greeting variable in a block before we assign its value?

    <script>

<!---->

    let firstName = 'world';
    let greeting;

<!---->

    $: console.log(1, greeting);

<!---->

    $: {
      greeting = 'Hello ' + firstName;
      console.log(2, greeting);
    }

<!---->

    firstName = 'Bob';
    console.log(3, greeting);

<!---->

    </script>

<!---->

    <h1> {greeting}!</h1>

Here, you might expect the labels to be executed in the order they are declared (especially if you've been conditioned by React's hooks invariable order rule). Except that they aren't.

In the console, we see 3 (with "undefined”) first, then 2, and then 1. Svelte, it seems, has set up a dependency graph: the block where there is the number 2 log has a dependency on firstName, and updates the greeting variable. The number 1 log has a dependency on the greetingvariable and is therefore executed afterward, once the greeting variable is changed. And Svelte manages these dependencies and executes the blocks in the order dictated by the dependencies, not by order of declaration.

As I have a twisted sense of humor, I immediately tried to create a cyclic dependency:

let firstName = 'world';
let greeting
$: firstName = greeting + 'hum';
$ :greeting = 'Hello ' + firstName;
firstName = 'Bob';

But the compiler detected it and gave an error, so everything is fine.

In conclusion

Now obviously there is a lot more to Svelte than what I have mentioned here: the components, the templating, the stores, the context, and so on. But that is all detailed nicely in Svelte's documentation.

To me, after this first taste, there are two questions: First, do I want to continue learning this framework? And is it suitable for me to introduce at work?

Svelte's originality and the way it introduces new behaviors in basic JavaScript syntax have whet my appetite. But by the same measure, I'm wary of putting this in the hands of junior developers, who might end up believing that Svelte is how javascript actually works in the wild.

Key Takeways

The Svelte Documentation

The Svelte Tutorial

Svelte Examples

Sign up to our newsletter

We help you better understand software development. Receive the latest blog posts, videos, insights and news from the frontlines of web development

We respect your privacy. Unsubscribe at any time.

Social
Made by kodaps · All rights reserved.
© 2024