You probably saw the results of stateofjs.com, and now you have a clear idea of what’s the best solution for everything frontend-related… Like, e.g., React, right?! :)
Hell, I hope no… it’s not that simple
The goal of this article is to provide an “opinionated” view of the current situation. There is no point in this being yet another post like “this is the list of individual framework features, and you choose what fits you best” It may help, but I believe the experience is a valuable asset as well. What I often see is choosing technology like React blindly based on popularity. The popularity is one thing, but you should consider more important aspects before choosing a framework, especially for enterprise applications.
Let’s define what I mean by “enterprise application” here.
It’s an application which may create a large ecosystem, compose several smaller application/libraries. It may have hundreds of sub-pages and dialogs. All of it being worked on by tens or hundreds of developers simultaneously. Enterprise applications usually need well-defined support, interfaces, the ability to scale, and a way to deal with technical debt incrementally. Enterprise apps usually contain many repetitive work and patterns.
The following article will focus on historical rivals, i.e. “React vs. Angular” and try to break/confirm historical dogmas. I’m not an ultra fan of neither technology, but you may meet them very often when “enterprise” requirements come to play, and you should at least consider those frameworks for use.
Popularity and what does it mean?
A few years back, imagine a similar situation with a survey (when Git was not spread widely) when someone asked you to give him your favorite source control software. At that time, many of you would say SVN, others would start with Git, less of you would choose CSV, but probably the lowest amount of people would say something like Perforce because they’ve never used it, and it’s expensive. Does it mean that tool is wrong for enterprise usage? No, it used to be very powerful software for source control and collaboration (designed for big companies & beating most of the competitors). It was not so “popular” because it was relatively expensive. Many students, self-employed developers, but even startups/companies didn’t know about it or didn’t need it for their small projects. So being the latest on the popularity list may mean less than you think. Don’t get me wrong, popularity is important, but sometimes it does not reflect reality, i.e. it does not provide answers to your question.
In the case of React, the popularity builds on a large ecosystem, indisputably. There are new React-based libraries introduced every day. The second thing-it’s pretty simple to learn. It costs you almost nothing to become React developer from zero to hero. The fact is that React itself is doing very little for you. The rest is about learning the ecosystem of your choice. That’s also the reason why the ecosystem is rapidly growing — everyone has a slightly different opinion about “how to solve” common things.
React also seems to be tempting for devs who just learned HTML, CSS, JS, and they’re seeking something fast and popular for building SPA but not wanting to invest more into new (mainly more complex) things, abstractions, and concepts (even if it may simplify upcoming days of their life)
From an enterprise point of view, popularity may gain more attraction when you need to hire new people. That’s true. But, IMHO, that’s also about how you hire because most mature developers want to build cool things and adapt to whatever !modern! ecosystem (and angular is still moving forward).
Angular followers must admit that its popularity suffers from AngularJS (v1.x) experience. People who jumped over to, e.g. React, might lose interest/track of new Angular features, performance improvements, and ways to improve web development.
React as an alternative for Angular?
No, not really… Let me explain why. There are too many articles about Angular vs. React, and most of them (definitely not all) are focused on comparing something you actually can’t compare. Angular is an alternative for React library (and more) but React is not an alternative for Angular. As you have probably heard many times, React is a library for building/rendering UI components. On the other hand, Angular is a full application framework, and there is a huge difference.
Let’s describe it in a simple picture.
According to the picture, it’s clear that React is a very small subset of the Angular framework.
You might hear very often that React is “unopinionated” and gives you “freedom.” That’s the truth, but in other words — welcome to the “do it by yourself” world. Compose your application framework, configure the toolchain, create your convention, rules, and abstractions. Many enterprise applications (its backend part) benefits from an opposite approach where e.g. Spring dominates for Java, .NET framework for C#/VB.NET based apps, and Laravel or Symfony for PHP. Modular huge frameworks (usually done by one vendor) covering everything you may need for app development on that particular tech stack. Nothing like 10.000+ npm dependencies to build a simple project. This approach is very popular and stable for backend development. You can consider Angular (and not only Angular) as a similar “big framework” for Typescript to build a frontend application.
What does it mean if you decide to go with React over Angular in your enterprise application?
If you decide not to use Next.js-like app framework, you have to figure out how to compose your application framework. React is one small part, but how about rest? You will end up with tens of 3rd party libraries of different owners to deal with particular areas of app development. Let’s see just a few examples below.
What seems to be boring on the Angular side may be a brilliant thing for enterprise apps eventually. Why? Because you need to bring some system and reliability into what you’re doing.
- All major parts are maintained/owned by the same vendor. You can be sure that those parts stay compatible with each other, you don’t have to be worried that one breaks another, and you don’t need to track any compatibility matrix between those libraries. It also happens that some libraries get out of maintenance — that’s something you probably don’t want to deal with in your enterprise application.
- Upgrade planning and maintenance — it’s enough to check Angular changelog or Angular Update Guide to see what changed, what’s new, and what’s breaking. Usually supporting automatic updates. Everything at one moment in one place. In comparison to checking tens of 3rd party (sometimes semver-less ) libraries with different release cycles without the possibility to automatically update everything at once.
- You can still use whatever library to achieve what you want. So you have some level of freedom, but you usually have no real need to use something else because Angular parts are very well integrated into the whole framework.
Many people with marginal Angular experience say:
“Yeah, but Angular is so big and I don’t need all of those, why should I bring this into my application?”
This is very common and it only shows limited knowledge of how (new) Angular really works. This presumption is usually related to the AngularJS v1.x time period (which I’m not speaking about). Angular 2+(and mainly 9+) is a totally different framework. It does all things like lazy loading and advanced tree-shaking (so it does not happen that you pack something you don’t use)
Strong conventions for development
React does not give you the ultimate guide on how to effectively deal with things like forms or dependency injection, routing, libraries, etc. There is huge friction between developers. Everyone has their own best practice, their own combination of libraries, and way how to handle e.g. form validations. It kind of reminds me of the Linux ecosystem situation (especially distros). The ecosystem is moving so quickly that the community can’t settle on anything. You have to work hard to bring order into this and set up rules to avoid the wild west—everything to realize that all you did yesterday is not cool today. Usually, every project has a different setup and libraries (= even if you know React; it’s still a new world). On the other hand, Angular lets you screw up, but at the same time, it’s an opinionated framework, and it tries to guide you in the right direction. Google also prepared an Angular coding style guide that gives you “best practice advice” and recommendations directly from creators, not only for one piece of the puzzle but for whole application development. There is a huge chance that anyone who knows Angular will be able to jump on your project immediately, knowing most of your tech stack. Most of the React teams I met didn’t go beyond React documentation and best practice to write components only. They don’t look too much at the whole application infrastructure and rules how things should communicate together (but of course, there are always bright exceptions). This is not about blaming people. It is about React library not helping here.
Prepare for DIY attitude and more work
React nature is very low level. What React does really well is the composition of components. Still, it does not offer any features like optional two-way bindings, e.g. built-in support for conditional CSS classes, real class abstraction for components (i.e. class methods can’t be called on component instances without specifying them as arrow function or binding it to “this”). Moreover, there is no alternative to Reactive Forms (declarative way to deal with forms & validations), no advanced rxjs-based HTTP clients by default, etc.
Form handling examples:
As you see, the example above is an official example of a “class” based component written in React to create a simple form with one text input that alerts the inserted message once you hit the button. You can write it a little simpler by using “function” based components (introduced in v16.8) and e.g., omit binding of handlers in the constructor. However, both options share manual handling of state and its distribution, even in a very simple scenario.
On the other hand, the angular example does not force you to manipulate the state by yourself (it makes it invisible). You will set “value” as the model of input, and then if the input has changed, the value will change as well. You don’t need any special handlers. If you modify the “value” property in the onSubmit() method, it will automatically change it in UI as well. Also, it’s clear that you don’t need to use arrow functions blindly for everything to handle “this” state correctly because Angular handles that for you in this scenario (heavy usage of arrow functions may increase the memory footprint of your app). It’s also popular to use the native “Reactive Forms” approach for more complex forms. It allows you to define an HTML form template and provide it with a simple configuration object handling both — config & values. VueJS is using a very similar mechanism of handling state changes, and I would say they were heavily inspired by some Angular pieces (e.g. “v-model”, template approach, and others)
The last example is a small rising star in the category “boilerplate killer.”
From a dev perspective, it’s kind of relief to work on an app with such simplicity (similar to desktop development or the JQuery era when everything was “simple”). However, that should be the goal of good enterprise architecture — maximum value for minimum price and effort.
Angular and VueJS (or Svelte/SvelteKit) go further; thanks to advanced techniques (better integration between internal libraries, enhanced JS compilator, or proxy objects), they offer real simplicity & comfort to write an application in 2021+. You may object, “I have to write much more code in Angular even to start the project” — you’re right, but this is being mostly a one-time investment that goes back to you in a later phase of big project development. Once an application is bootstrapped, adding a new component is pretty straightforward (even through CLI). In React, you may start simple, but the complexity grows granularly over time, and then you realize, “oh, this is probably not a good way how to handle plugins,” so you refactor and refactor…
I was mainly stuck with template bindings here, but there are many other features and abstractions which may simplify your life and boost your productivity:
- Integrated IoC/DI with the possibility for overrides, multi-providers, etc.
- One/Two-way bindings, proxy objects without the necessity to use boilerplate in the form of useState, useCallback, useEffect, and still keep best practices.
- Optimizing the rendering speed based on template limitations (sounds weird, but it’s a real thing)
- Built-in support for conditional styles, pipes
- Built-in code-splitting
- First-class typescript support
- Input parameters as real typed properties (no generic arrays, supporting whole objects, and an array of objects passed from template)
- Observable-based interfaces
It’s interesting to see how frameworks are being compared nowadays. Pretty minimum interest is on “how easy/fast it is to build and maintain something bigger, " but most of the comparison is heavily focused on performance aspects. It’s not weird. Performance is very important — but not at the moment when you fight with other frameworks for every byte of bundle size (i.e. 35kB vs. 37kB!)…
AngularJS is much older than React, and to be honest, React came as a savior when AngularJS started to reach its limits for modern applications. React was much faster and lighter, no doubt. They came with Virtual Dom, which was a kind of revolution at that time. That was a pretty obvious and understandable reason to migrate to React. It was ~2015… but since then, we moved a bit.
I don’t want to be rude, but React is more or less in the same (good) place. Of course, there were huge improvements over the years (e.g. concurrent mode, hooks, caching), but most of the stuff was introduced because Virtual Dom proved to be slow (it was always slow, but still better than alternatives). Since React is pretty low-level, most of the work related to enhancements is up to the developer, and that’s where the additional boilerplate is coming from.
Angular (in comparison to AngularJS) made huge improvements in the whole framework. It’s basically a new thing. The biggest evolution was finalized in v9 when the Ivy renderer became production-ready. The Angular modular concept is the answer for “the bundle is too big”, it involves tree-shaking and native code-splitting (lazy routes). Ivy itself focuses on speed and bundle size. Angular 2+ used to use Virtual Dom as well. Still, they dropped it with Ivy and started to use Incremental DOM, which should increase performance on small devices (phone, tablets), especially bundle size and memory footprint. Everything was done with backward compatibility in mind (luckily for companies). Angular architecture does not allow smooth integration with Snowpack or ViteJS (in terms of cold-start of dev server in few secs, loading ESM modules file by file), but at least Ivy comes with technology that allows you to recompile only components you are changing.
So, how does comparison look in reality?
As visible above, there is no sense to decide between Angular and React based on performance. One field where Angular may seem to be little behind is “script bootup time,” but given the fact it’s a one-time operation, and you compare 6ms vs. 80ms, you will not see the difference in real life. If you use frameworks properly, you will get very similar results. The era of a huge performance gap between those two is gone. Even bundle size for Angular Ivy application is much smaller and comparable to React. Comparing the same RealWorld example app you get 140kB (angular) vs. 193kB (react+redux) vs. 97kB (react+mobx). This difference is tiny, and it proves that the technology allows you to be efficient. It is pretty much on you to screw the performance e.g. by taking some untreeshakable dependencies :)
If you are really demanding regarding the performance and care a lot about it (you may do some heavy visualizations, games, or just run on minimal resources), don’t use angular and react. Svelte or VueJS may be the right mature-enough candidates.
As you probably know, you can take both technologies and create whatever. It’s possible, it will perform well, and you will adapt yourself to whatever you choose after a few weeks. How efficient is that as an enterprise solution?
Developer efficiency and comfort (Angular)
Let’s assume we already have a developer who is familiar with a stack. In this case, I have to say that Angular may provide better value because the framework has clear guidelines, and advanced abstraction (runtime magic) will allow you to avoid repetitive boilerplate in many places. At the same moment, Angular works on simplification of fundamental pieces in Core design (e.g. avoiding the necessity of NgModules etc.). It’s definitely harder to learn but considering it as a one-time investment. I believe Angular may provide comfortable long-term development.
What I really disagree with is that if you use React you are much faster in delivery. It’s nonsense, and it is usually based on a comparison of two different things. E.g. two applications of similar complexity, but one is doing proper testing, documentation, and other duties you should regularly do.
Maintenance, stability, and security (Angular)
React ecosystem is powerful and risky at the same time. Too risky to blindly choose React and “something” unless you have good reason to do that. The more dependencies you have in your application framework, the more tricky it is to stay up-to-date because everyone releases their bits at a different time, and you can’t plan in advance (which is an essential aspect for enterprise development where hundred people may depend on a singular platform). Sometimes your dependencies become incompatible with each other or force you to update a bunch of other dependencies. I believe this is not related to React only; this is related to the whole UI world. It’s moving too fast, so you should find a “stable” spot that will help you effectively drive your project. Angular with regularly planned major releases (2x per year), following SemVer with clear LTS strategy, supporting 1 release back without breaking changes. And having Google as the only vendor you have to rely on… is not that bad.
Of course, even Google makes mistakes, unfortunate promises, etc. It’s not that long we have been prepared to write our own runtime localization for Angular since they promised it twice with no results. Fortunately, the last release came with all the beauty. It seems that something similar is regular in other frameworks as well — What’s NOT new in React 18 — DEV Community.
Flexibility (Angular / React)
Generally, React wins here. That’s clear. On the other hand — you should consider what’s better for your business. Is it super-flexible but possibly unstable (with all stuff described above)? Or being “flexible enough” to do the job you need to do and move your project forward. Create actual value instead of rebuilding the build chain every second month? Having the possibility to combine everything with everything is not that important for enterprise development. The important thing is to choose mature, scalable technology and believe it will live for a few years. Flexibility also may bring diversity to a unified codebase.
Again, from a company perspective — React wins. You have a bigger chance to find React developer at this moment (perhaps even a bit cheaper). The fact is it’s simpler to be React developer. You, as an employer, just need to count on the price of onboarding them on your library composition, the price related to investment into high-level abstractions to not repeat patterns and work (avoiding boilerplate as much as possible). Creating own culture and let React developers fight for their opinions on the unopinionated library.
If I have to choose from those 2, then I would probably still lean towards Angular for a long-term project (at this moment). I don’t believe React itself deserves such attention. Despite many cool improvements, development in React does not feel so comfy in 2021. Don’t get me wrong, there are awesome technologies out there, and React’s the only advantage is being compatible with most of them. React is good for simple apps, cool for prototypes, great for complex rendering logic utilizing the power of JSX, but not sure about enterprise-scale (where I don’t believe that being “unopinionated” is necessarily a good thing). I know, not only Facebook is a nice example of an enterprise-scale, but they have a huge history with React, and they’ve already built their application framework on top of it. I believe many people do not share my opinion about React being so “low-level,” and even If I attempt to believe them, I would still have to recommend at least Next.js for enterprise-level apps. It is an effort driven by Vercel to bring some rules and built-in functionality into a unified application framework for React developers. Only that (and similar pieces) could be considered as an alternative for Angular in its scale. Where I can see React is as a tool to create e.g. UI component library. That’s an area where you don’t need Angular complexity. You can also wrap such components as web components and simply create reusable framework-agnostic components in React. The question is whether you even need React for this or if you go with something like Stencil or Svelte…
It’s worth saying that if you already have an extensive codebase using Angular or React (consuming its latest versions), it does not worth rewriting it. There is a minimal benefit you may gain (considering the fact you already invested a lot). However, it does not justify the price. If you want to modernize or move performance to another level, you have to risk more and look at other options below.
Also, being completely honest — If you build a true enterprise application, you would probably end up with many tech stacks :)
Back to alternatives — If I don’t have to choose either one, I would probably give more chances to VueJS (on ViteJS) since it is here for several years already (getting more and more popularity). It’s still not heavily used in companies, but I strongly believe in its architecture (the work with Virtual Dom, using a proxy object for reactivity, and more). It has a proven record to be a really performant framework (beating both above). I really love to see how they try to be opinionated and still modular as much as possible. There is also thing like https://nuxtjs.org/, which handles unified tech stack for most common things. Vite solves my issue with Angular being bundle-oriented-only in the dev environment.
I also mentioned Svelte, and I think it could be revolutionary in UI development. Still, I don’t feel it’s mature enough to be chosen for enterprise development on a bigger scale (at this moment). Sapper is dead, and the only replacement (SvelteKit) is being finalized and still young. Let’s wait for what happens there.
Another killer candidate for enterprise solutions is definitely Blazor WASM. Yeah, it’s pretty unstable right now, but once this beast is done, I would not be afraid to say we may have numero uno for enterprise apps (especially those who have .NET backend). Having a .NET framework in a browser may be a game-changer — but that’s for a different topic.