I’ve been overseeing UI projects for … oh, decades now. I’ve shipped production applications in backbone.js, SproutCore, Angular 1, Angular 2, React/Redux, even going back to the old days of the Adobe Flex ecosystem with Cairngorm, PureMVC, and Parsley. I’m old, I’m grouchy, I’ve been around the block a few times, I’ve made all the mistakes.
I still think Angular is better than React.
Now, don’t get me wrong – I understand the appeal of React, and why Angular’s a tough sell (even though they can work together rather well). React’s learning curve is lower, it’s not a full framework, you can add React to an already existing application easily, while Angular (to be effective) requires a full rewrite. It’s very easy to get started with React, while Angular has a famously steep learning curve. React doesn’t force much on you, Angular… really does. As a result of this, most ‘comparisons’ I’ve found out there are poorly informed, and rarely overcome the resentment of “why are you making me use ThingA rather than ThingB I’m used to?”
And, lastly, React is the “sexy JS library du jour”, hand in hand with Vue.js. That counts for a lot, even though this is the Bandwagon Fallacy.
The React Snowflake
The first reason I dislike React, is because it encourages snowflake projects; projects that are different enough in their other technical decisions as to be effectively unique. This is often put forward as one of the “nice” things about React, however I consider it its worst shortcoming.
To illustrate, let’s list out a few of the other decisions that go into a project:
- Build system: Webpack, Gulp, Grunt, Bazel, Babel?
- Data layer: RxJS, Redux, MobX, too many to list.
- In-app navigation: HTML5, #! based, React-navigation, etc.
- Linting rules: Single-line vs multi-line variables, 2 vs. 4 spaces, etc.
If the above seems mostly irrelevant from your point of view, then I hazard to guess that you are working on a small team, where the learning curve and arguments around these technical decisions is lost in the churn of on-boarding. Either that, or your organization has put a lot of work into enforcing consistency.
“There should be one– and preferably only one –obvious way to do it.”
In the Angular ecosystem, most of the above decisions have been made for you. As a result, if you switch between Angular applications, it’s very likely that are that you’ve seen it all before. While on the outside this seems authoritarian, in reality it is highly liberating – you are free to focus on interesting technical problems, instead of fighting the tabs-vs-space battle for the upteenth time in your career.
In short: React encourages divergence, while Angular encourages consistency.
Feature Reuse (it’s more than just code)
If your company is successful, it will grow. This usually means additional projects, such as admin dashboards, white labels, or even entirely new products. The way this usually happens is with a copy/paste of the existing project, deleting all the bits that aren’t needed for the new application, at which point the implementation details begin to fragment. This especially becomes a headache when trying to maintain a consistent user experience, as one button may evolve away from the other.
This is where Angular really shines, though I’ll have to dig into technical details a little to make my point. In short, Angular is actually an Inversion of Control engine. You build a component or service, and then provide it to the Injector to manage. This can be done individually, or groups of components can be bundled together in a ‘Module‘. These modules are powerful – as an example, you could build a UserProfileModule that, when injected, takes over the /user/profile path in any application that it’s provided to (it can even be lazy-loaded). Other modules can provide ambient features, such as the popular Angulartics2 metrics library.
As you can see, this is much more powerful concept than simple ‘code reuse’, as entire features can be not only shipped, but trivially imported. It’s one of the advantages of the heavy guard-rails that come with Angular – if everyone agrees on how to build lego’s, then it’s easier to fit them together.
So now, let’s return to the above problem. You’re creating a brand new application, and rather than copy/pasting from existing codebases, you add a dependency on an angular library that provides you with modules that you want to use. If the library updates, you do too.
A more concrete example of this is VMware Clarity. One of the reasons we’ve been so successful at maintaining a consistent UI across all of VMware’s SaaS Products is because our UI components come in one easy-to-use module.
Technical choices are business choices
Are you in a startup, planning to be acquired? Are you in a large organization, with multiple projects that need to maintain a common look & feel? Are you about to face a major re-org? Is one product being moved to maintenance while another is being built?
These kinds of changes are common, as our industry is very dynamic. And speaking as someone who’s been involved in Technical Due Diligence, I’ve seen acquisition deals fall through because technical decisions made by the prospective organizations would be too difficult to reconcile.
In the end, every technical decision we make is a strategic one – which is one of the reasons I’m a huge fan of the Choose Boring Technology philosophy. With that in mind, recall that an Angular application can use React components, while a React application cannot easily use an Angular application. In other words, it’s easier for you to adopt another organization’s code if you start with Angular, even if they’re React-based.