Is Svelte the future of JavaScript Frameworks?

Over the years, JavaScript development has gone through several paradigms: from raw AJAX in vanilla JS to a long reign of event-driven frameworks such as jQuery and Mootools, to the current state-driven approach of the current champions such as React, Vue, and Angular. 

But in an era where everyone is looking at performance, accessibility, and developer experience, there’s a new contender that promises to deliver all of these through a radical new approach to building apps. Is Svelte the next big thing in JavaScript frameworks? 

The Evolution of JavaScript Frameworks

In one way or another, we’ve been building web apps even before the word “app” was coined.

Early interactive websites gathered the power of AJAX to provide improved navigation and even what we may call the first SPAs. But the crude state of JS made for an excruciating developer experience, making apps increasingly hard to deploy and maintain as they grew.

In 2006 John Resig created jQuery, and the era of event-driven frameworks was born. After a quick challenge with MooTools, jQuery rose as the go-to framework for anything front-end, and it reigned supreme for a good decade. 

But as applications grew bigger and more complex, the need to share data across components drove a paradigm shift towards other approaches. After a brief and quick burn of Ember and AngularJS, we ended up with the current champions, that in one way or another aim towards a declarative, state-driven approach to frontend development: React, Vue and Angular. 

React is currently the most used and one of the most sought-after skills in all of tech, which provides an incredibly rich environment, a ginormous user base, and pretty much a guaranteed job for anyone that learns the ins and outs of the library. 

This has its downsides too, most notably developers using React for places where it may not be the best option. We see simple institutional websites built with React and a bunch of add-ons all the time, something that honestly feels like driving a nail with a sledgehammer: sure, you’ll get the nail in, but you’ll probably take a good chunk of the wall with it. But even in applications that really need a tool like React, it’s easy to find bundle sizes getting out of control, contrived codebases with increasingly painful developer experience, and certain patterns where the user experience is seriously damaged by poor performance.

What is Svelte?

That’s where Svelte.js promises a bright new future, by providing incredibly lightweight and performant applications.

The key idea that allows it to do so is working as a compiler. Current frameworks/libraries ship with your bundle to run your declarative code in the imperative programming environment of the browser APIs. 

Svelte works as a compiler at build time instead, cutting down a huge chunk out of your bundle size. It only ships your code, with some enhancements introduced by the framework. 

But it doesn’t stop there. It also allows us to write far more efficient code by achieving true reactivity, something that no other library/framework comes even close to and provides a smooth developer environment that’s incredibly easy to work with, maintain, and scale. 

The Developer Experience Matters

One of the biggest challenges for any framework is providing a good developer experience. We don’t really build applications for the computers but for other humans, and that includes both the users and our fellow developers. 

There are a million things that influence how a system’s developer experience is perceived, but we can probably summarise a positive experience as providing an easier learning curve, better readability, less boilerplate, doing more with less code, and ease of maintenance. 

I would dare to say that the focus on developer experience is actually one of the main reasons why Vue was able to achieve such great success in a market dominated by frameworks/libraries built by industry giants, and why it’s so heartwarmingly valued by its users.

Svelte has put a great effort into this, leveraging the lessons learned from previous frameworks. It takes ideas from Vue such as single file components and even revendicates the old jQuery motto “write less, do more”. 

Vue-Like Single-File Components

Generally speaking, one of the most welcomed features of Vue is the use of single-file components, that is, the possibility to have our markup, styles, and logic all gathered in one place. Of course, like anything in tech, this is opinionated and has lots of asterisks and “it depends” attached to it, but for the most part, developers value the readability and modularity of SFCs. 

Svelte.js takes inspiration from Vue here and gets it to the next level. In any given .svelte component you can have a <script> tag declaring your logic, a <style> block for your CSS, and regular HTML tags defining your template. And I mean it. There’s no templating language in Svelte, not even the need to declare a <template> block. You simply write your HTML tags as you would in an old-fashioned HTML file, with added functionality via handlebars-like curly braces. 

<script>
  const title = "World";
</script>

<style>
  h1 {
    font-size: 2.5rem ;
  }
</style>

<h1>Hello {title}!</h1>
<p>This is my first Svelte component</p>

This is one of the things that in my opinion makes Svelte so welcoming for newbies: if you know HTML, CSS and JS, Svelte will look familiar the very first time you see it. And to prove it, check this bit of (slightly more complex) code and see if you can understand what it does:

<script>
  let count = 0;
  function (addOne){
    count += 1;
  }
</script>

<button on:click={addOne}>
Clicked {count} times
</button>

Pretty sure most people reading this, even those who have never seen Svelte code before but are familiar with HTML and JS, will immediately pick that we have a button that displays how many times it was clicked and updates through an event handler. 

Sure, some parts of the JavaScript syntax can get obscure (more on this later on), but it will still be relatively easy to understand. With Svelte there’s no need to learn a whole additional templating language like React’s JSx or understand the totality of the system before dropping a line of code as in Angular’s case. 

Scoped, Modular CSS

One of the biggest challenges of styling websites and apps is keeping control over the CSS specificity and scopes. As apps grow bigger, it’s fairly common to see blocks of CSS that no one dares to delete or modify, simply because you don’t know what it will affect. 

The Svelte framework addresses the issue by having your styles scoped to the module you declare them in by default.  You can add a <style> tag to your component without worrying about affecting anything else on the app. It achieves this by adding a computer-generated unique hash to the styles declared in each module. This gives you most of the benefits of CSS-in-JS with none of its drawbacks. 

For instance, consider this code:

/* app.svelte */
<script>
  import Nested from './Nested.svelte';
</script>

<p>This is a paragraph.</p>
<Nested/>

<style>
  p {color: purple; }
</style>
/* Nested.svelte */
<p>This is another paragraph.</p>

We have two modules, one nested in the other. The resulting app will show two paragraphs, but only the first one will be purple. If you inspect the compiled code to check how things are working under the hood, you’ll see that Svelte is creating a unique class, something among the lines of p.svelte-urs9w7{color:purple;}, and only applying it to the <p> elements explicitly declared in that module.

While I can see the huge benefit this provides for most teams, if you have a dedicated CSS specialist they’re probably yelling “just embrace the cascade instead” right now. I know I would… Well, turns out you can. 

Svelte doesn’t lock you into this architecture. You still have the option to affect nested elements with <style global>, and even the possibility to use pre-processors and whatever framework or architecture you’d like. It gives you a simple and effective way to handle your CSS, but you can override it with whatever other approach you prefer. 

Want to spice things up with SASS? you got it, just declare <style lang="scss">. Want to go with any flavor of CSS-In-JS for whatever reason? You can. Toss in Tailwind for your convenience? No problem.

True Reactivity

Some people say there are as many definitions of “reactive programming” as reactive programmers out there, and they are quite right. But the basic idea is defining the dynamic behavior of a value at the time of declaration.

A good example of reactive programming can be found in spreadsheets. When we declare a cell’s value we may do so in relation to other cells. This creates an intricate tree of relations that knows exactly which values depend on each other, it is aware of which cells should update and in which order whenever we make a change.

The declarative nature of current JavaScript frameworks is closer to reactive programming than the previous imperative ones, but still miles away from true, spreadsheet-like reactivity. React is, ironically enough, not reactive. To understand the difference, we should dive into how the frameworks really work. 

Older frameworks would make it such that any change meant a lot of unnecessary DOM traversing and re-rendering. For instance, when we deleted an element from a list all of its items would re-render, despite only one of them having actually changed. This is not a problem in simple interfaces, but it gets to disproportionate levels as things start to scale, as DOM manipulation is a lot slower than most other JavaScript processes.

The revolutionary, core feature behind React was providing us with a lightweight memory representation of the DOM that we can traverse much faster for manipulation. This is called the Virtual DOM.

When a change happens, React updates the virtual DOM, compares it to a previous snapshot to know exactly which elements have changed, and only updates those elements in the real DOM through a process called reconciliation or diffing. 

That’s why people claim that the virtual DOM is much faster than the real DOM. And sure thing, if you were to re-render the whole DOM for every change, using the virtual DOM and diffing is orders of magnitude faster.  

But what if we could let the application be aware of which elements should change without relying on any DOM traversing (virtual or real) at all? That would obviously be even faster. 

Well, that’s exactly what Svelte.js aims to do. Instead of relying on a virtual DOM and diffing, Svelte allows us to explicitly declare the relation between elements using topological order. The app always knows which elements should update and in which order whenever a change occurs. 

Let’s see an example to understand what topological order really means. Let’s say we want a variable B to always be twice of A. In regular JS code (and almost all programming languages and frameworks out there) that would require us to re-assign B every time A changes. For instance:

var a = 10;
var b = a * 2;
a = 25; /* a is 25, b still 20 */
b = a * 2; /* re-assigning b to update it to 50 */

When we change the value of A, we are repeating the assignment of B to keep it updated. Doesn’t look too terrible in that tiny bit of code, but in a true application, this results in unnecessary repetition and re-running of huge code blocks.

But what if there was a declaration that allowed us to persistently bind the value of B to A, in such fashion that whenever A changes, B changes along? 

That’s true reactivity and the intricate relation of how multiple reactive variables should change and in which order is the topological order. And that’s a revolutionary feature behind Svelte. 

Of course, there’s no native JS syntax for this kind of operation, so to achieve this while sticking to valid code, Svelte hijacks a fairly unused bit of JS syntax known as a labeled statement and makes it its own.  Going back to the example above, to keep the value of B bound to the result of A * 2, it’d be enough to declare:

let a = 10;
$: b = a * 2; 

Now, whenever A changes, B changes with it. 

Let’s see how this would work in our previous clicky button example by adding a paragraph that tells us the double.

<script>
  let count = 0;
  function (addOne){
    count += 1;
  }
  $: doubled = count * 2;
</script>

<button on:click={addOne}>
Clicked {count} times
</button>
<p>{count} doubled is {doubled}</p>

Of course, it doesn’t look like much in such a barebones example, but when scaled to real-world application level, this sort of responsiveness is nothing short of amazing, and results in clean code that updates the interface at incredible rates.

A Solution for the Current Performance Standards: Svelte

With increasingly more complex apps and increasingly more impatient users, performance is quickly becoming a key aspect of front-end development. Any app must strive to feel instantly responsive if you want the users to stay engaged (or to stay at all). Furthermore, Google’s recent page experience update puts a huge weight on performance as a ranking factor in its search results. Web performance can be the determining factor for your product’s success. In 2021, performance is the new SEO. 

Current frameworks have put a lot of effort in recent years to improve their performance, and for the most part, they are sufficiently fast to provide a good user experience and achieve satisfactory benchmarks for SEO. If your team does its part, the framework will probably not be the limiting factor for performance in computers and smartphones.

But the web is not just computers and smartphones anymore. We have all sorts of devices connected to the internet, and we may need to address them with equal importance. For instance, a payment terminal can have quite limited hardware resources, yet serving them a performant solution can be critical for a business’s success. That’s where the traditional frameworks simply won’t cut it, and your choices pretty much get limited to either vanilla JS or Svelte.js. 

My own introduction to Svelte was building a GUI for smart 3D printers that needed to be accessed by desktop, mobile, and an embedded Chromium browser on the printer’s own Raspberry Pi. We started building the project in React but it was made clear very quickly that the limited hardware resources would not be able to deliver nearly enough performance. 

That comes to show one of the biggest misconceptions in our modern front-end toolbox: people constantly repeat “the Virtual DOM is fast” almost as a mantra, turns out that’s not strictly true. It’s simply “fast enough”, but still an additional step. The virtual DOM is pure overhead. 

And I’m not making a breakthrough discovery here: the React team knows it very well, and that’s why they’ve been building abstraction layers above the basic virtual DOM to prevent unnecessary reflows with tools like shouldComponentUpdate, useMemo or useCallback, and amortization strategies like concurrent mode. 

But even if you’re a performance geek and very carefully craft your React app to achieve superb performance (which let’s be honest, most codebases out there are not even close), there’s no beating the compiled, reactive nature of Svelte. Building your application in Svelte usually results in writing about 30% less code than React, far smaller bundles thanks to its compiled nature, and a responsiveness several orders of magnitude faster. 

Built-In Accessibility Linting

In the last couple of years, accessibility is becoming one of the most sought-after skills in front-of-the-front-end development, and a critical requirement for any project. Whether that’s a legit strive for inclusion or simply fear of demands is a topic for a whole other article, but there’s no denying that building inaccessible apps and websites simply won’t cut it anymore. 

Considering this, Svelte has included an accessibility linter in its core. Whenever your app compiles, it’ll run an automated accessibility test and let you know through the terminal of any violations, for instance, missing alt text on images. It will still compile, so if for whatever reason you decide to build an inaccessible app it will let you get away with it but will be very vocal about how disappointed it is with you. 

Of course, this (as any automated accessibility test) doesn’t guarantee accessibility, and at the end of the day it’s still up to you to provide accessible code and user experience, but it’s great to have a quick linter built-in just in case we forgot something obvious.

Svelte Popularity: The Challenge of Reaching Critical Mass 

Let me share a quick, geeky analogy: when planetary systems are forming, some celestial bodies gather most of the system’s mass. Yet only those who manage to get enough mass to drive nuclear fusion turn into stars, while those who fall short by just a bit end up being gas giants. Quite literally, a giant ball of gas. 

The same is true for JavaScript frameworks or any trend in tech for that matter. Those who fail to achieve a certain user base are destined to be nothing but a giant ball of gas, no matter how magniloquent their promises are. 

And that’s the big challenge for Svelte today. In my eyes, there’s no doubt that it can provide a better developer experience and allow for more performant applications. Looking at it from a strictly technical point of view, I believe its pros clearly outweigh its limitations, and some of its features beat the current champions by miles.

But the industry values stability over everything else. Any experienced dev, and most stakeholders, would put great value in stability. They need to be sure that the code you write today will still be valid in the years to come, that they’ll be able to find other developers to maintain and further develop their app with relative ease, that they are investing in a solid choice and not a huge pile of technical debt or soon-to-be legacy code.

The Svelte framework arrives at a very stable moment in the front-end environment, so it will have to prove itself beyond the call of duty to make a dent in the market share. 

React reigns supreme and has been doing so for years upon years, and while Angular seems to be on a plateau or even a slight decline in relative terms, it still holds a big chunk of the share. Vue is perhaps the most surprising, considering that it is driven by the community instead of an industry giant, yet it still manages to challenge their hegemony, with some statistics giving it second place and slowly trending towards the top.

So while Svelte is leading the charts for developer satisfaction and interest, it’s hard to see how it could gain enough momentum to be a star and not a gas giant. 

Conclusion

There’s no doubt that Svelte brings interesting ideas to the table, allowing for incredibly fast applications, a great developer experience, and a strong aim towards accessibility, all of which are key aspects that can give it the upper hand in the near future.

What remains to be seen is whether that’s enough to challenge the current paradigm and its champions. The industry clearly favors stability and considering how widespread they are and the fact that React is backed by Facebook and Angular by Google, we can be certain they’re not going away anytime soon. It may even be that case that if Svelte ends up proving that compiling and/or true reactivity is the way forward, they may simply re-design themselves embracing the new paradigm while keeping some of their identity. 

Therefore, if you already master one of the current frameworks/libraries I’d recommend giving Svelte a try, but it may not be time to jump ship just yet. 

Are you looking to hire a JavaScript developer? You’ve come to the right place, every Scalable Path developer has been carefully handpicked by our technical recruitment team. Contact us and let us know what your needs are.