Update July 11, 2017
A reader on Reddit kindly pointed out that the current version of this article has several issues. So I’ll re-work this article and publish a – hopefully better – version soon.
Just think of performance. React enthusiasts never get tired praising the superior speed of React. Nothing can beat the virtual DOM, they say.
That may or may not be true. I didn’t run a benchmark, so I can’t say for sure. What I can say, is, that the Angular team has spent a lot of time thinking about performance. It has improved a lot since AngularJS. In general, Angular is fast enough for most applications.
Comparing what can’t be compared
If my CTO is right, you simply can’t compare React to Angular. Or, quoting Dan Halverson, comparing React to Angular is like comparing Hibernate to Spring. There’s some common ground, but the scope is completely different. React only covers the view layer. Angular is a full-stack framework covering most aspects a front-end developer has to deal with.
Thing is, our customers don’t care. They want us to suggest either React or Angular. And they are right. Instead of comparing the core libraries, we’d rather compare the ecosystems. So that’s what we’re going to do.
There are many differences between Angular and React. Many of them boil down to different approaches to tackle everyday problems. In other words, they follow different philosophies. The table shows the most important differences at a glance:
|application type||complex websites with many interactions||enterprise applications|
|optimization goals||performance and simplicity||developer productivity|
HTML backed by TypeScript code
|invasiveness||concentrates on the view layer||provides a full-blown ecosystem|
|directory structure||JS + HTML in a single file||separate code from the view|
|level of freedom||flexible; many options||opiniated; convention over configuration|
|feature set||there’s a third party library for everything||brings almost everything out of the box|
(no antagonist pair!)
|unidirectional data flow;
simplifying application state management
optional two- or one-way-binding
|target audience||applications needing high performance||enterprise applications|
By the way, there are also many similarities between React and Angular. When I started to research the differences half a year ago, I was surprised to learn that both frameworks share a lot of common traits. Both frameworks encourage you to build components. In fact, they make it so easy to create components that virtually everybody creates components without thinking twice. Compare this to traditional frameworks like jQueryUI, JSF, Swing, or JavaFX. Each of these frameworks allows you to create custom components. However, almost every project I’ve seen so far is happy to simply use third-party components.
If you’re using React or Angular, that’s not an option. Both frameworks are all about building components. Components are the building blocks of your application. Plus, they make creating components incredibly easy.
Project health check and legal stuff
Before starting to compare the frameworks, let’s run a quick project health check. According to OpenHub.net, both frameworks are very active projects. Funny thing is that seems to have for times as many lines of code than Angular. That’s probably because the React repository contains the documentation. In the case of Angular, the documentation has moved to a separate project.
Both projects have liberal open-source licenses. React is available under an Apache V2 license. Angular is published under the MIT license, which is even more liberal. You can use both frameworks in your commercial project.
Dan Halverson has collected a couple of statistics about the market share of Angular and React. However, I believe that the statistics reported by BuiltWith are misleading. Angular isn’t a framework for creating websites. Sometimes people do just that, but the result is usually disappointing. Angular is a framework for creating web applications. Most of them are hidden from public eyes like BuildWith because they run in internal enterprise networks.
Tool support, and ecosystem
Let’s get back to Cory’s article for a minute. Early 2016, he was concerned a lot about tool support. At the time, React was an established UI framework. Angular, in contrast, was still in its alpha-testing phase. The final release was published nine months late, in September 2016. So it’s not surprising that the tool support of Angular was mediocre at the time.
Today, there’s no reason to worry about the ecosystem. Most popular IDEs support Angular, including the HTML snippets containing specific Angular syntax. It’s a long way to the superior tool support of Java, but progress is fast, and it’s only a matter of time until the Angular support of the IDEs catches up. If I’m not mistaken, the market share of Angular is ten times larger than the market share of popular Java UI frameworks like JSF. In other words: there’s a major market demand. And the tool providers react to that pressure.
For some reason, TypeScript seems to be unpopular among the React community. I can’t say for sure, but I have an inkling this is where the different subcultures of React and Angular show.
Subculture and target audience
Angular gives you clear and strict guidelines. It’s very opinionated about many things. It stresses the importance of tests. It insists on using dependency injection. Angular even introduces its own module system on top of the standard module system of ECMAScript6.
All these peculiarities pay off in large-scale projects. In smaller projects, they are a nuisance at best. So it’s little wonder Angular attracts enterprise programmers. They’ve learned the value of strict rules. They are necessary just to survive if your average project exceeds 100.000 lines.
React, on the other hand, gives you a lot more freedom. There’s no reason why React shouldn’t work with a 100.000 lines project (it does!). But as a rule of thumb, React attracts programmers who value their freedom and who can afford to enjoy this freedom.
Unexpected use cases
Update Aug 11, 2017: Today, I’ve seen an unexpected use case. There’s a small WordPress plugin using React for its UI layer. WordPress sites tend to install dozens of plugins, so in general, it’s a good idea to keep the memory footprint of the plugin small. Depending on the configuration, the minified version of React.js adds only a few dozen to roughly 150 KB. If you need a small memory footprint, you’ll benefit from React.js. Angular offers many services to you, but that comes at a price. The memory footprint is roughly one megabyte. The Angular team is working hard to change that, but I doubt they’ll ever be able to compete with React simply because Angular is much more ambitious than React.
Library vs. framework
Often, this difference boils down to saying “Angular is a framework” and “React is just a lightweight library”.
In other words: Angular is set in its ways, and it insists on you following its ways. If you do, you get first-class support. No matter whether we’re talking about testing, dependency injection, communication to the back-end, internationalization, form validation: Angular’s got an answer. It’s an excellent programming environment if you’re willing to accept the proposals of the Angular team. I, for one, didn’t find a reason to complain about that yet.
React follows a different approach. It concentrates on the “view” part of your MVC application, and on simplifying the data flow within your application.
Everything else is provided by a third-party library.
On the first glance, that’s not a problem at all. Quite the contrary: there’s a library for everything. You can do everything you can do with Angular, and you can probably do it better.
The catch is that these libraries are developed and maintained independently of React. You’ll never know when (or if) they’re going to be compatible with the next update of React. All these independent libraries may be abandoned at any point in time, which accumulates to a substantial project risk. I don’t say you shouldn’t take this risk. All I’m saying is you should be aware of it. Chances are you benefit a lot. The downside is you always have to be prepared for developing a “plan B.”
As to my perception, Angular focuses a lot on developer productivity. Almost every feature of Angular has been created with large scale applications in mind. You need powerful tools to stay productive in such an environment. Dependency injection, the strong support for test-driven development, the module system are only a few examples. The Angular CLI is slightly different in that it allows you to create an application from scratch in virtually no time. That’s a big plus with respect to developer productivity, too.
Now, I’m sure that React programmers want to be productive, too, and I’m sure they are. But when I listen to them, they usually are thrilled about a different story. They emphasize the superior performance of the virtual DOM (a runtime topic). Sometimes they start raving about the advantages of the unidirectional data flow. That’s a developer productivity issue.
The ugly truth about unidirectional data flow is that it comes at a price. The popular Redux framework takes this approach to its logical end. It forces you to write five classes for something requiring a single method in Angular. Developers keep telling me this extra effort pays, so there must be some truth to it. But in my eyes, it’s strictly counter-intuitive. It’s something you have to wrap your head around.
So I’ve come to believe not every application benefits from the unidirectional data flow. Most applications don’t. React specifically supports applications like Facebook. Applications supporting countless user interactions. If every window influences each other window, unidirectional data flow is an important tool to stay sane. Luckily, most applications are a lot simpler. The average business application has a single modal window. Even better, it has a single user working on a dataset at a time. React solves problems most business applications don’t have.
By the way, you can add Redux to Angular, too. When I joined such a project, it alienated me because it’s a lot more work and I didn’t see any benefit. But that’s my opinion. Other developer embrace Redux enthusiastically. Maybe it’s a matter of taste.
The idea of Angular is to create web components. Among other things, this means your components use the shadow DOM. This, in turn, means you benefit from local CSS rules. You can define CSS rules for each component, without having to deal with name conflicts or side effect. Every CSS rule is applied only to the current component.
Currently, browsers don’t support web components well enough to activate the shadow DOM by default. So Angular emulates it by adding namespace prefixes to your CSS rules. From a developer’s point of view, there’s little difference between the two approaches. Both work well. The advantage of the shadow DOM is that the HTML code looks nicer in the browser’s HTML inspector. In practice, you will hardly ever mind the difference.
Be that as it may, being able to use dependency injection is a nice trait of Angular. It adds a little to the learning curve, but not much. Using dependency injection makes your application a bit more abstract, so it may not be the right tool for every team. That’s one of the questions without a simple answer. Some teams are better off with DI; others prefer the bare-metal approach. Ask them, and keep the corporate culture of your project in mind.
Unidirectional data flow
I’ve already mentioned unidirectional dataflow. It’s one of the hot topics of React. The React community claims that unidirectional data flow simplifies programming a lot.
The Angular team has adopted unidirectional data flow as an option. There’s still the
ngModel which made AngularJS so popular. But nowadays, it’s only one of two options. The other option is to implement reactive forms. This approach gives you more influence over how the user input is processed.
Another benefit of adopting the unidirectional data flow is that it makes implementing the virtual DOM easier. The virtual DOM is a feature unique to React. The idea is not to render every change in the browser. That’s expensive because the browser immediately starts to redraw. React renders the new DOM tree into a virtual DOM. The virtual DOM is simply a memory structure. So rendering to it is blazing fast. After processing the user input and the events modifying the virtual DOM, React detects what has really changed and redraws only the modified regions of the screen.
That’s a big difference compared to frameworks like JSF which force the programmer to define the region which is updated beforehand. This region is updated on every AJAX request, even if only a small part of it has changed.
Angular doesn’t use a virtual DOM, but the Angular team has refined the change detection mechanism of Angular2 a lot. Changes are propagated down the component tree. So it’s always clear which components need to be redrawn. The dreaded update loop of AngularJS is a thing of the past. As to my impression, the change detection mechanism of Angular is almost as efficient as the virtual DOM of React. Performance is hardly ever a good reason to reject Angular.
Unique features of Angular
Both Angular and React propagate single page applications. That means that navigating to a different page isn’t really navigating to a different URL and redrawing the page from scratch. Instead, a part of the DOM is replaced during navigation.
This is a built-in feature of Angular. React doesn’t support routing, but there’s a library for that.
Angular has also a nifty HTTP service. This service simplifies calling REST services a lot. It also integrates seamlessly with the rx.js library. Angular accepts that HTTP calls are always asynchronously, and adds support for asynchronous actions by using
Observables. There’s even support for asynchronous calls in the HTML dialect of Angular. I’m referring to the
async pipe, which waits for data until they are delivered by the HTTP call.
Services are another key feature of Angular. React doesn’t know the concepts of services. If a component needs to use data, the data either has to be passed from another component further up the component tree, or it has to be provided by the global application state. The latter requires you to use an add-on library like Redux or Flow.
Cordova allows you to create mobile apps for multiple target platforms with a common code base. As far as I know, you can use it with both React and Angular. It’s an interesting choice if you need to access the hardware of your smartphone beyond what HTML5 allows.
The Ionic SDK is a mobile-first or mobile-only variant of Angular. It’s built on top of Angular and provides a component library supporting iOs, Android and Windows phones. The disadvantage of Ionic is that it doesn’t support desktop PC. But that’s a deliberate decision.
There’s also a project compiling Angular code to native machine code. I don’t know much about it, so I point you to this comparison between React Native and Angular NativeScript.
Wrapping it up
No matter which framework you choose, you can’t go wrong. Angular usually attracts developers used to working in a large enterprise. Angular, and the Angular CLI in particular, guides you all the way to the final application. The drawback is that you can’t tweak and twist the framework to fit your specific requirement. On the plus side, you’ll hardly ever want to do such a thing.
If you need full control over your application, you’re better off with React. Plus, React is optimized for a different class of applications. If you’re worried about the application state, opt for React. If performance is the number one issue, opt for React. If you’ve got complex user interfaces with multiple input and events, each potentially influencing each other window, opt for React. If you need an application with a small footprint, opt for React. However, if you’re programming traditional form applications, you’re better of with Angular. Plus, if developer productivity is more important than flexibility, opt for Angular.