In the last couple of months, I worked on an Indoor Map solution where we used Svelte to develop the user interface. It was a surprising decision because I had never worked with this tool, so I dedicated some time to learning about it and starting to set up the environment to work above it.
Intro
For people how are not familiarized with Svelte, this is a new kind of framework in the frontend world. But it's more a language than a framework. There is a lot of confusion on the Internet about what Svelte really is and whatnot. Some people mention that Svelte is a compiler that compiles your code into plain Javascript, which is not entirely true. Because like other frameworks Svelte is adding an internal package to do that everything works correctly.
Svelte is an extension of the Javascript language which helps you to create reactive sites. This means that there is some Svelte code that only works in a Svelte environment, not as a normal Javascript. But all this code is compiled to be able to run in any browser.
How svelte works?
One of the main thing that svelte does is syncing the template with the code. Let see an example:
<!--- Home.svelte --->
<script>
let name = "Dani";
</script>
<h1>Hello {name}</h1>
As you could see this svelte file has two sections. First, the script where we declare the variables that we want to use and next to an HTML text where we could use curly brackets to map the variables into the template.
But how this magic works? Well, one of the things that Svelte doesn't do is use a VDOM algorithm. They don't have a representation of the DOM, they just process the updates directly to the DOM, which in most cases, improves the performance.
<!--- Home.svelte --->
<script>
let name = 'Dani';
function onChange (e) {
name = e.target.value
}
</script>
<h1>Hello {name}</h1>
<input type="text" on:change={onChange} />
Let see what Svelte is doing in this simple case:
- When the
h1
renders, they detect thename
variable as a dependency, soh1
will subscribe to all updates that thename
will have. - When
onChange
modify the value, the compiler adds an update method below your assignment
// pseudo code
function onChange (e) {
name = e.target.value
$$update("name")
}
This method will get all the subscribers to the variable name
and run the updates.
Pay attention to the word that I used before, assignment. This is important especially when you work with complex data types like arrays, objects, or others.
function updateComplexValue () {
arr.push(2);
}
The previous code will not trigger any render update, because the compiler doesn't see any assignment. So, it's so simple as adding what the compiler is expected to trigger the render.
function updateComplexValue () {
arr.push(2);
// This doesn't do anything. Just tell the compiler that we need a new render
arr = arr;
}
So in terms of logic, this doesn't change anything. But now the compiler identify an assignment and they could add the update method below that.
// pseudo code
function updateComplexValue () {
arr.push(2);
arr = arr;
$$update("arr");
}
How does reactivity work?
The reason why I think that svelte is more than a simple framework is for this reason. Svelte add reactive declaration which allows you to create a new type of variable, a computed variable (as Vue called 😉). Variables or blocks will be updated every time based on their dependencies.
For example:
let firstName = "Daniel"
let lastName = "Acuña"
let name = `${firstName} ${lastName}`;
The name
will always be "Daniel Acuña" because there is no mechanism that said that each time that firstName
or lastName
change we need to regenerate the variable. But but but, Svelte extends the language to do it possible.
let firstName = "Daniel"
let lastName = "Acuña"
$: name = `${firstName} ${lastName}`;
Now you will have name
variable, which is reactive and is dependent on firstName
and lastName
, each time when these updates name
will be calculated again.
Also, you could use it as a block that runs in every update.
let firstName = "Daniel"
let lastName = "Acuña"
$: {
console.log(`${firstName} ${lastName}`)
}
How empower reactivity?
Reactive programming is not just about magic things going on. It's about events, subscriptions, and streams. Svelte create their own stores that allow you to use streams to share info between components.
// count.store.js
import { writable } from 'svelte/store';
export const count = writable(0);
// Counter.svelte
<script>
import { count } from './count.store';
let value = 0;
count.subscribe(newValue => {
value = newValue;
})
</script>
<span>Count: {value}</span>
// Increment.svelte
<script>
import { count } from './count.store';
function onClick () {
count.update(n => n + 1);
}
</script>
<button on:click={onClick}>
+
</button>
We are just sharing a structure to two different files, and as you could see we are subscribing in a component to be able to read the current value, but we also need to unsubscribe. However, all the subscription management could be annoying if we are using a lot of stores. So svelte, again, create a syntaxis to do it more easily to everyone.Reactive programming is not just about magic things going on. It's about events, subscriptions, and streams. Svelte create their own stores that allow you to use streams to share info between components.
// Counter.svelte
<script>
import { count } from './count.store';
</script>
<span>Count: {$count}</span>
Using the $
symbol, we are let that Svelte managed the subscriptions. So when the component mounts it will be subscribed and when the component unmount it will trigger an unsubscription. We just need to use it in this way to show the value.
The interface that svelte proposes to the subscription is completely common, so you could change it with any library that uses the same contract. The famous stream library RxJS is one of the cases for example.
If you want to empower the reactivity into Svelte, Rxjs is a good choice to take. Because you open the door to new possibilities to manage the streams.
If you are really interested in learning more about how to integrate RxJS with Svelte, I highly recommend this post by Tim Deschryver. https://timdeschryver.dev/blog/unlocking-reactivity-with-svelte-and-rxjs
Some consideration
Svelte is a open source framework but the community doesn't dedicate time to develop useful libraries to work abov it.
For example, if you try to find UI libraries to work with a Desing System you could find some libraries for Material Design with a lot of accesibility issues. Maybe one of the best options is Carbon Desing but all this depend of what do you want kind of app you want to develop. In addition to that, the integration of this libraries needs a extra set some extra configuration in your project to do that everything works.
Some UI libraries recommendation:
Also, svelte has a tech dep for some useful functions and components that they not provide yet. For example, they provide a way to render components dynamically (<svelte:component />
) but not a way to use dynamic element (I imagine, something like <svelte:element/>
). You could check the current status of this feature in this issue #2324.
Althought, this is a framework in development with a lot of improvements to do. Currently, Rich Harris the creator of svelte is moving to Vercel, so we should wait for new and cool things comming. Check the news
Conclusion
Svelte is so free that you could create whatever kind of code that you could imagine. This comes with pros and cons, but it all depends on your experience working with the reactive site.
If you are building something small like a micro app, svelte could be a good fit to choose. If you would like to learn about reactive programming maybe is a good place to start learning by doing so stuff.
Svelte has a really good future and also is putting in discussion a lot of pre-conceptions that other frameworks have. So I feel that it will help in the next generation of front-end technologies.
Top comments (2)
thanks for noting your observations.
hint: svelte:element is supported since svelte 3.47.0
fwiw: I disagree that Svelte is only suitable for small sites. In my opinion it scales quite well. (Especially if you build upon SvelteKit)
I wrote this post a couple of mouth ago. Despite I don’t use Svelte in my job, I could agree with you today, it’s easy and scalable. Easy for new devs, and scalable because you could create awesome things above it.
Nice! I didn’t check the svelte:element but it was necessary, happy to hear that.