Svelte is a direct competitor to highly opinionated frameworks like Angular, React, or Vue. However, it works a bit differently. While, in all three of them, your whole view’s code goes through the framework and is executed in the runtime in a browser, Svelte aims to do as much work possible on a compiler level. It has three main calling cards:
- Write less code
- No virtual DOM
- Truly reactive
Write less code
One such example is state variables. In React, if we want to have a variable causing a component’s rerender, we need to use either setState or useState (depending on how we’re writing the code). On the contrary, in Svelte, any variable in code declared in a component can cause rerendering without additional boilerplate.
Secondly, similarly to Angular, we get two-way data binding. That means that developers don’t need to manually write support for data inputs (like in React); they just need to tell which variable to update and look for the value.
Also, as with Vue, component code is contained in special files that have HTML with template syntax, CSS styles, and JS scripting, all divided into clearly separate parts. We don’t have multiple files for one component, as we do in Angular, or mix HTML inside JS, as we do in React. By the way, Vue’s syntax has been influenced by Ractive.js, a direct predecessor of Svelte.
There are several other things that make coding in Svelte faster, but it would take a whole article to show all of that awesomeness.
No virtual DOM
Virtual DOM (VDOM) became a buzzword with the release of React. React creators talked a lot about how great it is and how it boosts performance, being faster than the real DOM. However, React still uses DOM next to Virtual DOM. It just works so that, before actual rendering, everything is first done in-memory inside VDOM. The differences are then rendered to the user via a real DOM. That approach is not unique to React, it is also used in Vue.
But using real DOM without diffing in Virtual DOM can also be fast. That’s what Svelte (and Angular) are doing. Instead of keeping an in-memory copy of the whole page, Svelte knows precisely what should be updated and does it directly in the DOM, omitting the additional step. If you’d like to get more into technical details, you can read on Svelte’s official blog how it successfully skipped using Virtual DOM and why it’s better: https://svelte.dev/blog/virtual-dom-is-pure-overhead.
I’ve already touched on the topic of variables causing the rerender in the ‘write less code’ section, but I noted that it works just for the internal component state. To be honest, what we often need, especially in larger apps, is a global state that is not just a singleton variable but implements a reactivity in some way, e.g., using an Observable pattern. We want the global state to let every user know that the other part of the app has changed it. That’s where many state management libraries are coming in; these include Redux, MobX, RxJS, VueX, to name just a few. Most of these frameworks work in the way that we need to use a particular function to update the state and use another function to subscribe for updates.
To be precise, MobX does it in a very similar way without the compiler step. However, this creates a considerable overhead in terms of library size, which is not the case in Svelte.
I know, you may say, “Wow, Svelte is amazing, but [enter your favorite UI framework here] offers me server-side rendering, so I don’t need to use a browser for that.” I can agree. That is fantastic, especially for pages made with SEO in mind. There are remarkable frameworks for that, such as Next.js for React, Nuxt.js for Vue, and Universal for Angular. It shouldn’t come as a great surprise to learn that there is also one for Svelte. It’s called Sapper and is very similar to Next.js. The only drawback is that it is still in the early development phase (as of November 2020). Unfortunately, it will never hit the 1.0 milestone since it’s in the process of being rewritten into a new library called SvelteKit. You can read more about it and its future here: https://svelte.dev/blog/whats-the-deal-with-sveltekit.
Will my app weigh less?
That’s the most intriguing question and one for which we need some hard evidence. I decided to do a simple app in the four frameworks I have mentioned in the article (in the most straightforward way, using standard build templates, without additional optimizations) — Angular, React, Vue, and Svelte. The app is a simple click counter. If you’d like to check the source code, you can see it on the GitHub repository: https://github.com/tswistak/svelte-vs-other-frameworks.
After building the app in a production configuration, we got the following sizes for JS files:
|Framework||Weight of all JS files|
Unfortunately, Svelte is not perfect. The most significant disadvantage is its current lack of popularity. While React gets nearly 9 million weekly downloads, and Vue and Angular boast around 2 million, Svelte hits just 100 thousand. That means that it has less comprehensive community support (though it’s not so bad!) and less ready-made components (including UI frameworks). But, looking at NPM stats, we can see that the number of downloads is continuously growing; therefore, we can confidently suppose that there will be a steady improvement over time.