23-Dec

JavaScript

New kid on the block

The world of front end frameworks is always evolving. For years it was dominated by jQuery and Backbone, but these days we hear most talk about React and Vue. However, there is another framework that hasn't been talked about so much, namely Svelte. Although this framework is actually three years old, it had a rebirth in April this year with the release of its third major version.

4 min read

·

By Henrik Hermansen

·

December 23, 2019

Rethinking reactivity

Svelte was created by Rich Harris, a graphics editor in The New York Times. While working with data visualization with loads of nodes and lots of small changes he encountered problems with performance. Frameworks like React and Vue use a virtual DOM on which the framework can perform diffing and calculations to perform effecient updates of the DOM, seemingly in a reactive manner. This mostly works great, until a point where diffing and calculations actually becomes a bottle neck. Rather than trying to improve this technique Rich wanted to change the way we think of reactive changes.

Rich took his inspiration from good old spreadsheets. When you change the value of a cell in a spreadsheet, the program instantly knows to update all cells referencing the changed cell. In order to achieve this Rich didn't just create a framework – he created a compiler. Svelte knows all dependencies between your variables and DOM nodes at build time. This means it can create code which surgically updates specific nodes in your DOM. Hence the virtual DOM is no longer needed. The DOM is actually really fast when you know exactly what needs to be done. And what's more, this will create smaller and faster applications.

Svelte at a glance

Are you intrigued? Good. You should be. Now you know the core idea of what makes Svelte different, but I'm sure you're wondering what it looks like using Svelte. Much like React you will create components and each component has its own file. The basic structure of a Svelte component looks like this:

<script>
  let name = 'David';
</script>

<style>
  h1 {
    color: red;
  }
</style>

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

Because this is a component all code in your <script>- and <style>-tags are scoped. This means that the Javascript in this component won't affect other components, and your styling won't affect nodes from other components. Outside the scripts and styling we have some templated HTML.

What's with let?

Well let me explain. By default Svelte expects data to be mutable. What if we wanted to add an input field to the code above to allow the user to specify his name? With React you would need to create a state and run a set-function every time you wanted to update it. With Svelte you simply bind your mutable value to an input field and voilà:

<script>
  let name = 'David';
</script>

<h1>Hello {name}!</h1>
<input bind:value={name} />

For simplicity I removed the <style>-tag in this example.

Reactive declarations

One more thing you should know to truly make your Svelte code reactive is how to deal with reactive declarations. Say you want to show the users name in capital letters. Could you just make another let?

<script>
  let name = 'David';
  let capitalLetters = name.toUpperCase();
</script>

<h1>Hello {name}!</h1>
<input bind:value={name} />
<p>Your name in capital letters: {capitalLetters}</p>

If you run this code you would see the text Your name in capital letters: DAVID, but sadly this would not react to changes in the input field. In functional React components all your code runs on every render. In Svelte components your code only runs once.

When the value of the input field changes, there's no need to re-render the component. What happens is very straightforward:

  • the value of name changes
  • the text in the h1 node is updated

But Svelte has no way of knowing you also have an expression that depends on name. To solve this, Svelte borrows the Javascript label syntax to introduce the reactive declaration syntax$:.

With this in hand it really is a piece of cake to make reactive declarations:

<script>
  let name = 'David';
  $: capitalLetters = name.toUpperCase();
</script>

<h1>Hello {name}!</h1>
<input bind:value={name} />
<p>Your name in capital letters: {capitalLetters}</p>

Is this all?

No, no. That was just the basics. Svelte is actually rich on features. Both in terms of possibilities in the template syntax and helpful features you can import to your Javascript.

What I personally loved the most when I started making something with Svelte was how easy it was to add transitions. Although I am capable of making transitions with CSS, I loved how I could just throw in an element directive, and it just worked:

<script>
  import { fade } from 'svelte/transition';
  let showMessage = false;
</script>

<input type="checkbox" bind:checked={showMessage} />

{#if showMessage}
<div transition:fade>
  Hello world!
</div>
{/if}

I could go on for a while about all the built-in functionality of Svelte, but I'd rather you go try it for yourself.

P.S. if you're intrigued and curious, but feel guilty for betraying your current framework of choice, don't worry. Svelte was actually awarded the Prediction Award in this years state of JS, so you're not alone.

Up next...

Loading…