During the summer, I decided to test a few frontend framework to see what’s going on in this space and form a better opinions over alternatives to React. I tested Svelte because after hearing from it I felt attracted to it, Vue because it is popular, React to have a good comparison point and Angular because I was about to take a new job that required Angular. I also included Aurelia, the framework I first used to create the app I used to test all the others.
To do these tests, I decided to code a RSS reading app: you connect on the first page and you are then redirected to the list of articles and categories. You see the articles of the current category (the unread ones by default), you can switch categories, mark articles as (un)read, read articles on scroll and on swipe.
Aurelia is a complete frontend framework I used on some of my personal projects. The framework is really good although a lot less known than the alternatives. From my experience, the community is small but very active. The main drawback I experimented was the lack of good tooling (things may have changed, I haven’t used Aurelia in a while).
The framework has pretty much everything you may need: a way to define components, dependency injection, a HTTP service, a logger… You can also use libraries that manipulate the DOM directly with it.
When I created the first app years ago, I had a good experience using the framework. I can’t really say more today. Please note that, just like with angular, the framework is big and designed to create apps, not enhance a page and that the resulting bundles can be big.
Last but not least, the app is rather big: 1,764 lines of code (1387 of TypeScript, 231 HTML). Part of this is explained by the fact it has features no other apps have (like offline support with a Service Worker).
Svelte is a relatively new framework. You can use it as a library to enhance your pages or as a framework (with SSR, routing, stores) thanks to svelte kit. It has lots of features and a good community.
It’s the first framework I used during my tests. I found it easy to handle. What I specially liked is the way you define components: everything goes into the same file, you use a good templating language for your HTML that reminds me of the Django one and you define your CSS for just your component. Overall, it feels like you are using standard tech. Same goes for the stores: it feels like I was using JS and you can easily use them outside Svelte if needed (although reading values isn’t easy)!
I decided to use Skeleton to help me style the app. I think it was either a wrong choice or that I needed to configure it better to have something more pleasing to the eye.
What I found interesting is that the framework also help you define animations on elements. It help me a great deal to do the read on swipe feature correctly. Beware though, by default, it also tried to animate all the articles when I switched categories which created slowness and bugs (we didn’t really change the page). Understanding and fixing this took me a long time (but it occurred again with other frameworks, so it’s not a Svelte thing).
I didn’t like how reactive statements work: dependencies are implicit and I encountered a problem where a statement was run each time an object changed while I was only concerned with one of its properties.
I also found strange that I had to run two commands to compile the app and have all the errors.
Last but not least, the resulting app size is small: 1,317 lines of code (450 lines of Svelte, 978 lines of TypeScript).
Vue is the main competitor to React. It’s a rendering lib you can extend to have all you need (router, store…). Most of these "extensions" are maintained by vue.
In terms of structure of a component, it’s very similar to Svelte. The way it handles state is very similar to React while being less verbose.
When I tried to add translations, I choose vue-i18n which seemed like a popular choice. But I couldn’t extract strings automatically. Using FormatJS which is compatible with both React and Vue might have been a better choice (although I never succeed to make string extraction work with it).
I think that watchEffect works a bit better than in Svelte, even if they also rely on automatic dependency discovery.
I also found strange that I had to run two commands to compile the app and have all the errors.
I didn’t do read on scroll nor read on swipe: I found no easy helpers to help me and wanted to spend time on other tests.
Last but not least, the resulting app size is small: 1,165 lines of code (444 lines of Vue, 717 lines of TypeScript). I’d say on par with Svelte given it’s a bit smaller but I have less features here.
A tiny thing I found strange: with the default rules, semi-colons are not used. I don’t think I encountered any other default with this rules.
React is probably the most popular one. It’s a rendering lib you can extend with lib maintained by third party to meet all your needs.
Here you are forced to use JSX to define your components. I have always disliked it since I think it forces you to do React things to define your view and your behaviors. On the bright side, you can define multiple components in the same file and create many tiny reusable components.
The hooks system to perform side effects or have cached values is very verbose but also very explicit about dependencies. It has pros (it’s obvious and you can manage them by hand if needed) as well as cons (it’s verbose, easy to forget without a linter, if some deps are missing you must document why).
Material UI is an astonishing component library: complete, well documented and easy to use. It’s the best component library I used.
One the good side, you can view all errors in one command.
I found a helper lib to help me implement the read on swipe.
I also tested for the first time the new features of Redux: async thunks. I think that having this included out of the gate is a good thing as we won’t need to rely on external libs to perform something that we almost always need to do. Redux is still very decoupled in different concepts: it makes it very clean and also very verbose.
At last but not least, the app is rather big: 1,684 lines of code (630 TSX, 1219 TypeScript).
Angular is a big batteries included framework. It’s the one that has the big enterprise touch and the one where you don’t really need to install anything but Angular libs to achieve your goals.
It contains everything you need from the HTTP router, Angular Material to help you design your UI, Service worker service, form validation and building… to dependency injection. It also comes with more concepts: components, directives, services. Like Aurelia, it is centered around classes whereas other framework are more centered around functions. By default, a component is split into 3 files: the TypeScript code, the HTML and the CSS.
Its binding system is also more complex: while in all other frameworks you can bind anything, here you must bind data and event (to provide output to your component) in a different manner. If you just bind a function, call it won’t refresh the state of your app.
You will also need to learn and use RxJS since it is heavily used by the framework, including its HTTP service. It’s a world of its own that will take you time to get used to (let alone master), will increase the size of your bundles but is very powerful and even pleasing to use once you get the gist of it.
During development, I found that it required more full page reloads than any other solution. It’s a pain since it can make you loose context and may force you to reenter data/reopen modals.
While it includes a translation system, it was way too complicated for my needs. I felt it was tailor for big enterprise usage. Luckily, I could use another library that was more aligned with my needs.
At last but not least, the app is quite big. I had to do some improvements to limit the size. It’s better that the raw one, but still big. I have 1,859 lines of code (1,590 TypeScript, 286 HTML, 132 CSS).
To run the size tests, I always used a full reload on each page.
|Link to project
|Lines of code
|Connection page size
|Articles page size
|Good framework, not really known/used. Tooling could be improved.
|37 requests to load 1.57MB
|39 requests to load 1.66MB
|Very good framework, pleasant to use, modern and lightweight.
|18 requests to load 235KB
|18 requests to load 240KB
|More or less the same as Svelte. After these small tests, I’d favour Svelte over Vue.
|1,165 (but some features are lacking)
|7 requests to load 220KB
|9 requests to load 231BK
|Solid framework, good community, possibilities to make native app, very good components libraries. Shows its age.
|7 requests to load 528KB
|8 requests to load 530KB
|Complete framework, heavy to use and load. Overall good dev experience even if it’s verbose.
|8 requests to load 1.04MB
|7 requests to load 1.04MB
I enjoyed testing these frameworks and dive into their differences. I loved Svelte the most: code is pleasing to write, I like its architecture and conventions, the community is big enough so you shouldn’t have any problems (or if you do, someone should be able to help). I’d probably pick it to start my next project if I were starting from scratch.
Vue seemed nice too. But a bit stuck between Svelte and React, like I could have part of the joy of Svelte while still having to endure a bit of pain from React.
React is my least favorite by far. I’ve had a long and complex relationship with React, always failing to understand the hype around it (and more recently the hype around the hooks). I only used it because my job required me to. I was glad to see I could get exited by a frontend tech. For more on this, I invite you to read two articles by Josh Collinsworth who expressed quite eloquently this feeling I have: The self-fulfilling prophecy of React and Things you forgot (or never knew) because of React.
Angular is its own beast. If you work in a big enterprise, it’s probably the best choice for you. I think it can be pleasing to use, but it’s also complex and verbose.
In a nutshell
- There is a world outside React.
- You should probably checkout Svelte or Vue if you haven’t already.
- Keep a very close eye on web components: they are very likely to be the future. In fact, whatever you are using and whatever your opinion is (or just because you have little time and cannot checkout many things), just keep an eye on that. You can read this article to get a good start.