Building today — Angular 2 or React?
I recently gave a presentation at my employer contrasting “building applications in Angular 2” against “build applications with React”.
This is certainly a very controversial topic. Angular 2 has very little in common with Angular 1, whereas React inspired many of the changes in Angular 2. Now that Angular 2 is in beta, Google is saying that it’s ready for most developers to start building applications.
It’s almost an unfair comparison given that Angular 2 just hit beta in December, but it hasn’t stopped people from asking the question or comparing these two approaches to app development.
A word about Flux
One thing I’ve heard a few times is that you need “all these things” to be productive with React. One of “those things” is cited to be Flux. This seems to be a misunderstanding of what Flux is and what it accomplishes.
Angular 2 doesn’t actually address the problems that the Flux architectural pattern solves (though if you wish to be pedantic, it does provide some optional tools to help). As Flux is merely a pattern — much like MVC, MVVM or MVP — as long as you follow the pattern you can implement Flux using most any framework or library.
As I see it, Flux is about two things: unidirectional data flow and immutability. You can build React applications without either of these things and you can build Angular 2 applications with Flux. You can also build apps that exclusively use 2-way binding in React, if you really want to.
Language and Type System
Angular 2 has three 1st class language APIs. TypeScript, ES5 and Dart. They are working to provide better support for ES6 and Babel. If you choose TypeScript, you’ll need to use the type annotations to get any benefit. We’re also waiting on finalization of the ES7 decorators proposal which Angular 2 makes heavy use of. Visual Studio and VSCode have experimental support for decorators for now, though WebStorm seems to have great support for them.
It should also be mentioned that VS2015 has both JSX and TSX (React JSX in TypeScript) support, and there exist TypeScript type definitions for React.
Angular 2 doesn’t seem to have their own native app framework, though Telerik’s NativeScript was featured on the Angular 2 blog, which is still in experimental stage.
The folks at Rangle.io are working with the Angular 2 core team to create “Batarangle” for Chrome as an extension. You’ll need to download and build it yourself today.
Right now, it’s certainly easier to find pre-baked components for React. There are curated lists of components, like js.coach and there’s Facebook’s own list on github. You can find more information and better documentation about React on Stackoverflow and googling around. There are already a number of videos and blog posts about Angular 2, but some of them are still out of date, and you have to be careful with your search criteria or you’ll end up with false hits against Angular 1.
My current employer makes much use of Telerik’s Kendo UI widgets. Telerik is working on supporting Angular 2, but their currently public experiment as of this writing uses an alpha release and doesn’t work in all browsers that I tested. I’ve written a component to embed Kendo UI widgets here for React. There’s also this library here that has seen around ~80 downloads per week for embedding Kendo in React.
It’s better to have Kendo-like widgets implemented purely in either framework, as you get the speed and server-side rendering benefits. There already exists such a project for React here.
React is established and battle-tested, and companies like Paypal and Netflix seem happy with their choice to embrace it. It helps that Facebook eats their own dogfood and uses it in Facebook, Instagram and Whatsapp. A few things I wonder with Angular 2 are … how dependent will Google be on Angular 2 and how will Dart, which has seen widespread alleged adoption internally at Google, play into this picture?
Up And Running
In order to bootstrap an Angular 2 application, you’ll need ES6/Promise shims, Reflect-Metadata shim, Rxjs, Zone.js, and a compiler/bundler/minification pipeline for TypeScript/ES* (unless you plan to use their ES5 APIs).
To build a basic React application, you need only React and ReactDOM, the latter of which is only a few kilobytes unminified/uncompressed. For Visual Studio/C# developers, Facebook has the ReactJS.NET nuget package, which makes it easy to plug-in and get started with JSX without having to worry about setting up babel, npm, webpack and so on.
Most likely you’ll want a library for AJAX, routing and validation for your React applications. For AJAX, you can use a fetch polyfill (the next-gen standard already implemented by Chrome and Firefox), the established “axios” library, or even jQuery by itself if it lives on your pages already. For routing, use the “React Router” library.
For validation, I’d personally take a different approach. In Angular 2, we recognized that embedding the validation logic in our templates as in Angular 1 was not the best way to define it. Angular 2 introduces “model-based validation”, allowing you to decouple your validation logic from the markup. If you’re building an app using Flux, your reducer(s) can calculate your validation state and then your UI components need only be concerned with how to render that state. This makes it trivially easy to test your validation concerns along with the rest of your application logic and decouples it completely from your UI components and even from your UI library/framework of choice.
Size and Speed
React, even with an AJAX library, router, Redux, ImmutableJS and validation code (in the neighborhood of 200kb), is still much smaller than Google’s own minified copies of the bare-minimum to get Angular 2 running on a modern browser like Chrome (well over 400kb).
In my own biased, unscientific tests, bootstrapping a “Hello World” application in React was 2x as fast as Angular 2. Even so, with in-depth knowledge of both frameworks, speed should not be your primary concern.
Cory House said it best in his React vs. Angular 2 comparison article. My professional experience so far building a production app in Angular 2 echoes his sentiments regarding exceptions thrown in Angular 2. Although at times Angular 2 does a really good job, it is still fundamentally parsing templates at runtime. Thus, there is only so much that can be done to prevent certain kinds of errors earlier in the development cycle and to give useful information when they happen.
React also has a reputation for giving helpful error messages and doing a good job of gracefully deprecating API (ie: in React 0.13 vs 0.14 you should now call ReactDOM to render components in the browser, but this still works in 0.14 with a console message warning). Angular 2 is still very much in flux, though they typically do a good job of updating their changelog on github.
Approach to Browser Compatibility
React’s approach to browser compatibility has been “popular browsers”. This means IE8 has enjoyed support since day 1, and no surprise since Facebook has been relying on React for their flagship product.
Angular 2’s approach to browser compatibility is to use the most modern / bleeding edge tech, and then shim in support where necessary. The difference is significant, since you can expect React to “just work” whereas you need to make sure you include all the bits you need for Angular 2.
React will be sunsetting support for IE8 in the next version, but of course they wont do anything to actively break it.
Hopefully you’re moving as much application logic as possible out of your UI components.
Adding 3rd party libraries with React should be familiar to most developers in that it works much like adding jQuery plugins. Drop it in a script tag and go. You can certainly opt to use ES6 import syntax with babel and the rest and that’s probably what I would choose given the right team of developers.
That I’ve seen so far using the beta, Angular 2 doesn’t currently expose a window-level variable unless you use the ES5 package for it, so “linking” to Angular 2 will need to occur as part of your packaging as opposed to being an option with the same APIs when using React.
In my opinion, React involves less risk, firstly due to the maturity of the library and community. Additionally, you can opt to bring in only the complexity you need (ie: what if I’m not building an SPA on day one?) and it’s easy to embed into other frameworks.
The latter is relevant (especially in large enterprise apps) because you can share component code. If you have legacy pages that use another framework like Kendo MVVM, Durandal, Angular 1, Knockout, etc. you don’t need to rewrite the component to get the same look and feel in those pages without rewriting the entire page. I presented on how to embed React in virtually anything and the slides are available here.