- React 16.x: bulky and featuring some features that may not be needed, but recently subject of a good optimisation and with nice new features, which made it different from the rest;
- Preact: virtually identical to React (before 16.x), after the changes to the “original” this became a bit “outdated”, but still a good option out of its lean footprint;
- Inferno: first on speed benchmarks since it was released a long time ago, surprisingly still the fastest of all libs that use the same syntax of React (before 16.x). It also comes with some extra features aiming performance (VNode);
- Deku: super lightweight framework featuring VDOM, without most React features, including state (meant to be integrated with a state manager);
- Stencil: lightweight footprint, React-like concept (state, props) although with a slightly different syntax, TypeScript support;
- Vue: works (by default) in the "Angular-way" also used by Aurelia, with a separate HTML view instead of small components in JSX. Very simple to grasp the basics, very lean syntax, clever CSS handling;
- VirtualDOM (the lib): just a wrapper for the virtual DOM, very simple lib with no frills whatsoever. Maybe too simple, would be good for an "almost total vanilla JS" approach, which is not necessarily the case.
- Polymer: used to be a big player, now it is a bit outdated on some parts. They have lite versions of the component libs (lit-element, lit-html) that don't seem interesting for this case.
- Aurelia: although it is (IMHO) what Angular 2 should have been, I must admit it didn’t made me feel too enthusiastic, especially after learning how the two-way binding works (weirdly).
- Angular: I used to work with version 1 up to some years ago, but the versions 2 and above are completely different. I didn’t want to go too deep into this one – it is bulky and very opinionated, also harder to learn than it should be for the case. The documentation is inexplicably bad.
- Imba: a relatively new one, promises neat performance, it features a new pseudo-language that compiles to JS (a very nice one, although very different-looking) and has a very opinionated syntax that merges language and framework together. The documentation seems a little lacking to me, though.
- Redux: industry-standard "Flux-pattern" lib but very verbose way of bringing global storage, with immutability and very good event sequence control. Also requires a separate lib (Redux-thunk or Saga) to properly manage async changes;
- MobX: very simple on its core concept (not Flux-pattern) and lean on the coding requirements, has some additional features a bit harder to grasp;
- Satchel: a new lib from Microsoft to manage state changes in Flux pattern, still needs MobX to work properly.
- VueX: not similar to MobX, it is a Flux-like lib for Vue, very well-written.
- Also, there is a possibility to deal with global state using React's new context API.
- Jest: the official test lib from React/Facebook team, does most of what is basic to test, mostly for React components; for React projects it is good to be complemented with AirBnB's Enzyme.
- Mocha/Jasmine: older libs to do unit tests. Jest does what they do, and more;
- AVA: simplified syntax testing, not only for React components. I like the syntax and the approach in general.
So, this is my research. Those below are my conclusions for a medium/big sized project:
For my project, I wanted something that could be at the same time easy to manage/code and to learn (for whoever that may maintain it and doesn’t know the framework beforehand). For that we should drop Angular which is too opinionated (and whose documentation is confusing), Imba which is too different (no matter how nice it may be) and VirtualDOM, because it would require a lot of boilerplate code. Polymer and Aurelia didn’t seem interesting for me from the start and Deku was nice but the footprint generated (according to the tests I’ve read) is incompatible with its lean size. Stencil seems very nice to me, but the integration with a state manager (a special version of Redux crafted by the Stencil team itself) seems clunky and too verbose (even more than the original Redux-over-React itself). If we didn’t need state management (which we need for this project's size) it would be a top contender.
So, I came down to React, Preact, Inferno and Vue. I worked with React on the past 4 years, so for me it is a safe call. Lately it is changing a bit its API, deprecating things like ComponentWillMount and ComponentWillUpdate, which were used by pretty much everyone, in favour of stimulating a better architecture, which is a nice move IMO. Preact and Inferno are similar, both almost identical to React in API (before 16.x -- let's see if the follow React from now on), Preact has an especially small footprint, Inferno has a special craft for performance. Vue has another way of working by default but it is surprisingly flexible (it can have separate templates like Angular/Aurelia and also components with JSX like React), being also very simple and fairly easy to learn.
Any of the options above have to have a complement by the current requirements: a state management tool. A centralized state makes the whole application much easier to development, without the need to pass states to children and parents. Redux is the industry standard now but I wouldn’t like to adopt it as it is too verbose and needs a lot of boilerplate and even other tools (to manage async state changes) like Thunk and Saga. Satchel is not a good option as well (it uses MobX to achieve its goals, so why not using just MobX?). MobX is super nice and lean (despite the need for an external persistence helper when needed) and is the tool of choice if the choice is one of React/Preact/Inferno. VueX is surprisingly lean and simple for a “Flux” tool (also needs a persistence helper in our case but, in this case, it is basically a one liner).
Tool of choice for the POC: First vue, then Preact. I have chosen Vue first because of ease of use and learn, lean footprint, the ability to be unopinionated enough to make the developer free to chose its own approach. Also fairly good performance (better than React according to all the benchmarks I’ve seen) and also because I wanted to deal with a way of templating different than the React-like and JSX one (basically HTML inside JS). Turns out templating is not that nice to me (explained below) and I didn't want my team to have the burden of yet another different tool to deal with (they were dealing before with Aurelia and now with Preact and Stencil.js). So I'm sure Preact will do the job nicely.
-
Regarding the project build, I was about to use Webpack, which is now pretty much industry-standard but instead I found this nice little build tool called Parcel and it is really smart, actual “zero-config” like they advertise. If not fitting into any edge case, I believe this tool could replace Webpack nicely and save a relevant time;
-
Regarding the tests Ava is really simple and easy to use, but it needs another tool for mocking external services and another one for coverage collection. Sinon is one tool that can be used for mocking and Istanbul for the coverage reports, and despite the fact that it seems quite un-optimised to use three tools for testing, this Ava/Sinon/Istanbul bundle seems to work pretty much ok (Sinon and Istanbul are actually designed to be used together with something else);
-
So, Vue is awesome, it is indeed. Easy to learn and use, flexible and such. I must confess though that I was expecting separation of concerns like in Angular (which may not even be ideal), where you have the components separated in one HTML file and one JS file. This is possible in Vue, importing HTML files to the code, but it is slow and not recommended, as the HTML passes through an on-the-fly recompilation to convert this HTML into virtual DOM nodes that Vue uses internally. The “intended” way of templating here is through files that feature code, template and CSS with the “.vue” extension. Some people (me included) think that this file is not the ideal way of presenting stuff, but this is just a personal prefernce that may change over time (like JSX to me at some time ago).