Why We Moved From React to Svelte
Should JavaScript really be that complicated?

I feel I am getting old, ever so slightly getting on the “Should it really be that complicated?” bandwagon. Simplifying the process of creating dynamic front ends is getting quite chaotic.
When you work for a large firm and expect to maintain a product for many years, it’s a stellar solution. It’s best when everything revolves around a commonly agreed-upon workflow. React brings tremendous freedom around how you want stuff to work.
We are a small team that produce fast and iterative digital products for mid-sized to large clients — usually a few of them in parallel. We recognized that keeping up with the “fad of the moment” hurts our productivity. The React ecosystem changes paradigms every now and then. The temporal load of the projects makes maintenance a burden. We regularly roll back our brain to the way things transpired in the past.
Containerization made everything more comfortable because we could anchor the development environments in time. A considerable part of JavaScript fatigue is continually moving back and forth between the different bundlers and task managers — Grunt, Gulp, Webpack 1-2-3-4-5, Browsersync, Nodemon, blahhh! Now it’s all behind docker-compose, and it helps us sleep at night. Our CI/CD pipeline (almost) ensures that we are not doing dumb things in production.
But still, it doesn’t make us happier. React got tedious and boilerplatey.
I guess we all want to find that thrill of humble beginnings. Everything was exciting. “Look, when I click that button, that thingy moves. Holy cow!” But then you slowly realize that you included a 250kb library, wrote a class, fumbled with a shadowy representation of your DOM — bundled down with your fonts, your social security number, and the recent weather forecast. What the heck? Should it be that complicated?
I assure you we tried all the cool stuff before moving on, but like in a relationship that is slowly drifting apart, it was hard to tie back to the early and naive excitement. Every time something new got considered for testing, we instantly felt that overarching pressure to memorize past projects that didn’t use that paradigm. By default, the changes away from our “known” territory induced technical debt.
Onboarding new ninjas is a struggle for us. Sure, you can state in the application form that you are looking for experienced React developers, but there are many flavors. The holy wars of determining the right tools are getting old — just like me.
I look at the codebases with a feeling that I need to Marie Kondo the crap out of them to find any joy out of working with them.
So then we started our journey: Vue, Angular, Yew, Blazer, you name it. But we always came back with our fix because we, developers, are creatures of habit.
We focused precisely on what creates either a great developer experience or direct value for our clients. These lenses reduced the hassle and time involved with changing our toolbelt. We settled on our custom-built server-side-rendered React project and very few libraries that we liked for the longest time.
Then Svelte Happened
I was doing my usual YouTube surfing one night when I came across a video featuring Rich Harris (the originator of Svelte) explaining why React is not genuinely reactive. At first, it challenged me. Then the weight and clarity of his arguments were unavoidable. The way he presented Svelte as a solution to the problems he raised got me hooked. For once, here was a tool that solved problems rather than just attempting to do things a bit differently.
The first point worth noting is the shift from doing most of the work in the browser to doing most of the work at compile time. If you are like me, you obsess over your Lighthouse page speed results. To some extent, with the conventional approach, you would load in a massive library over the network that runs scripts and algorithms to get your page to display after the packet gets loaded. Doing so would hurt your page speed and SEO and generally give a terrible user experience where connections are slow. Sure, you could argue that tree-shaking and dynamic import is a solution. Then again, why make things so complicated?
Once you compile and build your first Svelte app, looking at the bundle size and content, you will see why doing the work up front makes sense.
One may argue that the incremental cost of adding components in Svelte is higher than with React. However, Svelte starts from a much lower spot, and for the type of work that we do, it’s a sweet place. The inflection is quite hard to reach (theorized between 500-1,000 components), so you have to be thinking about some massive applications.
On the other front of that argument, bundle size is not that important. It’s all about how hard JavaScript initially has to work to display your app and make it dynamic by loading (or not loading) your framework chunk.
It Compiles
Svelte is a framework, but it surely is a compiler first. The great thing with this approach is that the context can improve without you having to change your codebase much.
The compiler helps you avoid writing boilerplate by having helpful shortcuts to create your components or manage their state. Writing Svelte feels like going back to the Jquery days. Things were simple and interacted directly with your page.
Common patterns are abstracted with quick macros to help you bind state or values to components. Writing complex forms is now actually fun and easy. In the early months of truly building production apps with it, we had many “Aha!” moments when we found out about many helpers that make your life easier. All of them are baked in.
After using it for a while, our team found out that we write way less code now. Our component files are very concise and contain only the logic they have to deal with, with very few library imports.
One thing we have noticed after a while is that you may need an excellent machine to compile and run your Svelte project. As the project grows, we got violently long compile times (for front-end development, that is) ranging from 30 seconds to one minute for every update. We changed our old MacBook Pros to L15 ThinkPads running Ubuntu, and the same project went back down to a compile time of 700-900ms. The choice of ThinkPads over MacBooks is the subject for another article!
Svelte also has a more opinionated layer called Sapper. It will help you organize your project and give you server-side rendering as well as a service worker for free! You can build your SSR platform using only Svelte, but it can get tedious to maintain something of the same quality as Sapper alone.
If you genuinely want to have a progressive web app, it could be your most straightforward option. If you prefer working with a more defined architecture for your project, it will help you out because bare-bones Svelte comes with only a few tools for your architecture — most notably, no default router.
We also had to rethink how we work with styling our components. In React, you could do this in many different ways with styled-components or just doing good old CSS. In Svelte, you scope your styles with your components. The compiler cleverly renames your classes and CSS pointers so that your instructions don’t leak into other elements.
It feels like going back to writing styles and script directly inside HTML, but I am saying this in a “good” way. You can directly target things like H1
s inside your component without writing a placeholder class because it will coerce only this component. Over time, we felt that it makes it easier to reason about managing our CSS and maintaining it. It also makes libraries that have a bunch of helpers like Bootstrap useless. Less overhead!
It Makes Us Happy
In retrospect, I guess you could say it’s just another fancy framework, but we found the right tool for the kind of work we are doing. It may not be the best solution for everyone, but maybe this article will inspire you to give it a spin.
If you are interested in learning how Svelte works, the easiest and fastest way is to try out the interactive REPL online.
Let me know what your stories are!