Should I choose Angular or React? Each framework has a lot to offer and it’s not easy to choose between them. Whether you’re a newcomer trying to figure out where to start, a freelancer picking a framework for your next project, or an enterprise-grade architect planning a strategic vision for your company, you’re likely to benefit from having an educated view on this topic.
To save you some time, let me tell you something up front: this article won’t give a clear answer on which framework is better. But neither will hundreds of other articles with similar titles. I can’t tell you that, because the answer depends on a wide range of factors which make a particular technology more or less suitable for your environment and use case.
Since we can’t answer the question directly, we’ll attempt something else. We’ll compare Angular and React, to demonstrate how you can approach the problem of comparing any two frameworks in a structured manner on your own and tailor it to your environment. You know, the old “teach a man to fish” approach. That way, when both are replaced by a BetterFramework.js in a year’s time, you’ll be able to re-create the same train of thought once more.
We’ve just overhauled this guide to reflect the state of React, Angular, and their respective advantages and disadvantages in 2020.
Where to Start?
Before you pick any tool, you need to answer two simple questions: “Is this a good tool per se?” and “Will it work well for my use case?” Neither of them mean anything on their own, so you always need to keep both of them in mind. All right, the questions might not be that simple, so we’ll try to break them down into smaller ones.
Questions on the tool itself:
- How mature is it and who’s behind it?
- What kind of features does it have?
- What architecture, development paradigms, and patterns does it employ?
- What is the ecosystem around it?
Questions for self-reflection:
- Will I and my colleagues be able to learn this tool with ease?
- Does it fit well with my project?
- What is the developer experience like?
Using this set of questions, you can start your assessment of any tool, and we’ll base our comparison of React and Angular on them as well.
There’s another thing we need to take into account. Strictly speaking, it’s not exactly fair to compare Angular to React, since Angular is a full-blown, feature-rich framework, while React just a UI component library. To even the odds, we’ll talk about React in conjunction with some of the libraries often used with it.
An important part of being a skilled developer is being able to keep the balance between established, time-proven approaches and evaluating new bleeding-edge tech. As a general rule, you should be careful when adopting tools that haven’t yet matured due to certain risks:
- The tool may be buggy and unstable.
- It might be unexpectedly abandoned by the vendor.
- There might not be a large knowledge base or community available in case you need help.
- Both React and Angular come from good families, so it seems that we can be confident in this regard.
React is developed and maintained by Facebook and used in their products, including Instagram and WhatsApp. It has been around for around since 2013, so it’s not exactly new. It’s also one of the most popular projects on GitHub, with more than 150,000 stars at the time of writing. Some of the other notable companies using React are Airbnb, Uber, Netflix, Dropbox, and Atlassian. Sounds good to me.
Angular has been around since 2016, making it slightly younger than React, but it’s also not a new kid on the block. It’s maintained by Google and, as mentioned by Igor Minar, even in 2018 was used in more than 600 hundred applications in Google such as Firebase Console, Google Analytics, Google Express, Google Cloud Platform and more. Outside of Google, Angular is used by Forbes, Upwork, VMWare, and others.
Like I mentioned earlier, Angular has more features out of the box than React. This can be both a good and a bad thing, depending on how you look at it.
Both frameworks share some key features in common: components, data binding, and platform-agnostic rendering.
Angular provides a lot of the features required for a modern web application out of the box. Some of the standard features are:
- dependency injection
- templates, based on an extended version of HTML
- class-based components with lifecycle hooks
- routing, provided by
- Ajax requests using
@angular/formsfor building forms
- component CSS encapsulation
- XSS protection
- code splitting and lazy loading
- test runner, framework and utilities for unit-testing.
Some of these features are built into the core of the framework and you don’t have an option not to use them. This requires developers to be familiar with features such as dependency injection to build even a small Angular application. Other features such as the HTTP client or forms are completely optional and can be added on an as-needed basis.
With React, you’re starting with a more minimalistic approach. If we’re looking at just React, here’s what we have:
- class-based components with lifecycle hooks or simpler functional components
- state management using setState and hooks.
- XSS protection
- code splitting and lazy loading
- error handling boundaries
- utilities for unit-testing components
Out of the box, React does not provide anything for dependency injection, routing, HTTP calls, or advanced form handling. You are expected to choose whatever additional libraries to add based on your needs which can be both a good and a bad thing depending on how experienced you are with these technologies. Some of the popular libraries that are often used together with React are:
- React-router for routing
- Fetch (or axios) for HTTP requests
- a wide variety of techniques for CSS encapsulation
- Enzyme or React Testing Library for additional unit-testing utilities
The teams I’ve worked with have found the freedom of choosing your libraries liberating. This gives us the ability to tailor our stack to particular requirements of each project, and we haven’t found the cost of learning new libraries that high.
Languages, Paradigms, and Patterns
Taking a step back from the features of each framework, let’s see what kind of high-level concepts are popular with both frameworks.
Several important things come to mind when thinking about React: JSX, components, and hooks.
In React you can define components using functions and classes.
Class components allow you to write your code using ES classes and structure the component logic into methods. They also allow you to use React’s traditional lifecycle methods to run custom logic when a component is mounted, updated, unmounted, and so on. Even though this notation is easier to understand for people familiar with OOP programming, you need to be aware of all the subtle nuances that JS has — for example, how
this works, and not forgetting to bind event handlers.
Functional components are defined as simple functions. They are often pure and provide a clear mapping between the input props and the rendered output. Functional code is usually less coupled and easier to reuse and test. Before the introduction of hooks, functional components could not be stateful and did not have an alternative to the lifecycle methods.
There’s a trend among React developers to ditch class components in favor of simpler functional components, but with hooks being a newer feature, you’ll usually see a mix of both approaches in larger React projects.
Hooks are a new feature of React introduced in version 16.8. They are functions that allow you to class component state and lifecycle method features in functional components. There are two hooks provided by React:
useState for managing the state, and
useEffect for creating side effects — such as loading data or manually editing the DOM.
Hooks have been introduced to make functional components simpler and more composable. You can now split large functions into smaller atomic parts, allowing you to divide up related pieces of functionality — separating them from the rendering logic and reusing it in different components. Hooks are a cleaner alternative to using class components and other patterns, such as render functions and higher-order components — which can quickly get overly complicated.
React provides ways of structuring your application without involving a lot of complicated abstraction layers. Utilizing functional components together with hooks allows you to write code that is simpler, more atomic, and reusable. Even though the notion of combining the code and templates might seem controversial, separating the presentation and application logic into different functions allows you to achieve similar results.
Angular has a few interesting things up its sleeve as well, starting from the basic abstractions such as components, services, and modules, to TypeScript, RxJS, and Angular Elements, as well as its approach to state management.
Angular has a higher abstraction level than React, thus introducing more fundamental concepts to get familiar with. The main ones are:
- components: defined as specially decorated ES classes that are responsible for executing the application logic and rendering the template
- services: classes responsible for the implementation of business and application logic, used by components
- modules: essentially DI containers for wiring related components, services, pipes, and other entities together.
Angular makes heavy use of classes as well as concepts such as DI, which are less popular in the world of front-end development, but should be familiar to anyone with back-end development experience.
It’s also possible (and wise) to use TypeScript together with React.
RxJS is a reactive programming library that allows for more flexible handling of asynchronous operations and events. It’s a combination of the Observer and Iterator patterns blended with functional programming. RxJS allows you to treat anything like a continuous stream of values and perform various operations on it such as mapping, filtering, splitting, or merging.
The library has been adopted by Angular in its HTTP module as well for some internal use. When you perform an HTTP request, it returns an Observable instead of the usual Promise. This approach opens the door for interesting possibilities, such as the ability to cancel a request, retry it multiple times, or work with continuous data streams such as WebSockets. But this is just the surface. To master RxJS, you’ll need to know your way around different types of Observables, Subjects, as well as around a hundred methods and operators.
Similar to React, Angular components have a concept of a component state. Components can store data in their class properties and bind the values to their templates. If you want to share the state across the application, you can move it to a stateful service that can later be injected into the components. Since reactive programming and RxJS is a first-class citizen in Angular, it’s common to make use of observables to recalculate parts of the state based on some input. This, however, can get tricky in larger applications since changing some variables can trigger a multi-directional cascade of updates that’s difficult to follow. There are libraries for Angular that allow you to simplify state management at scale. We’ll have a closer look at them later on.
The great thing about open source frameworks is the number of tools created around them. Sometimes, these tools are even more helpful than the framework itself. Let’s have a look at some of the most popular tools and libraries associated with each framework.
A popular trend with modern frameworks is having a CLI tool that helps you bootstrap your project without having to configure the build yourself. Angular has Angular CLI for that. It allows you to generate and run a project with just a couple of commands. All of the scripts responsible for building the application, starting a development server, and running tests are hidden away from you in
node_modules. You can also use it to generate new code during development and install dependencies.
Angular introduces an interesting new way of managing dependencies to your project. When using
ng add, you can install a dependency and it will automatically be configured for usage. For example, when you run
ng add @angular/material, Angular CLI downloads Angular Material from the npm registry and runs its install script that automatically configures your application to use Angular Material. This is done using Angular schematics. Schematics is a workflow tool that allows the libraries to make changes to your codebase. This means that the library authors can provide automatic ways of resolving backward-incompatible issues you might face when installing a new version.
- ng-bootstrap for using Bootstrap widgets
- Material UI, for Google’s Material Design components
- NG-ZORRO, a library of components implementing the Ant Design specification
- Onsen UI for Angular, a library of components for mobile applications
- PrimeNG, a collection of rich Angular components
State Management Libraries
If the native state management capabilities are not enough for you, there are several popular third-party libraries available in this area.
The most popular one is NgRx. It’s inspired by React’s Redux but also makes use of RxJS to watch and recalculate data in the state. Using NgRx can help you enforce an understandable unidirectional data flow, as well as reduce coupling in your code.
NGXS is another state management library inspired by Redux. In contrast to NgRx, NGXS strives to reduce boilerplate code by using modern TypeScript features and improving the learning curve and overall development experience.
Akita is a newer kid on the block, which allows us to keep the state in multiple stores, apply immutable updates, and use RxJS to query and stream the values.
Ionic is a popular framework for developing hybrid mobile applications. It provides a Cordova container that’s nicely integrated with Angular and a pretty material component library. Using it, you can easily set up and build a mobile application. If you prefer a hybrid app over a native one, this is a good choice.
Angular universal is a project that bundles different tools to enable server-side rendering for Angular applications. It’s integrated with Angular CLI and supports several Node.js frameworks, such as Express and Hapi, as well as with .NET core.
Augury is a browser extension for Chrome and Firefox that helps to debug Angular applications running in development mode. You can use it to explore your component tree, monitor change detection, and optimize performance issues.
Compodoc is a static documentation generator for Angular. Similar to other documentation generators, it can create static HTML documentation based on the TSDoc comments in your code. Compodoc, however, comes with convenient features specifically for Angular, such as browsing your module structure, routes, and classifying classes into components, services, and so on.
Ngx-admin is a popular framework for creating custom dashboards with Angular and using either Nebular or Angular Material as the component libraries.
There are plenty of other libraries and tools available in the Awesome Angular list.
Create React App
Create React App is a CLI utility for React to quickly set up new projects. Similar to Angular CLI, it allows you to generate a new project, run the app in development mode, or create a production bundle. It uses Jest for unit testing, supports application profiling using environment variables, back-end proxies for local development, TypeScript, Sass, PostCSS, and many other features.
Similar to Angular, React has a wide variety of component libraries to choose from:
- Material UI
- Semantic UI
- Onsen UI, optimized for mobile applications
- Blueprint, for creating desktop applications
State Management Libraries
The introduction of hooks has certainly shaken up state management in React. There are ongoing discussions if there even is a need for a third-party state management library. Even though hooks address the immediate need for working with the state, other libraries can still push this further by allowing us to use time-tested implementation patterns, lots of additional libraries, and development tools.
Redux is a state management library inspired by Flux, but with some simplifications. The key idea of Redux is that the whole state of the application is represented by a single object, which is mutated by functions called reducers. Reducers themselves are pure functions and are implemented separately from the components. This enables better separation of concerns and testability.
MobX is an alternative library for managing the state of an application. Instead of keeping the state in a single immutable store, as Redux does, it encourages you to store only the minimal required state and derives the rest from it. It provides a set of decorators to define observables and observers and introduce reactive logic to your state.
Unlike Angular, React does not provide native CSS encapsulation capabilities, so you need to look for third-party solutions. There are numerous solutions to this problem, with no clear leader amongst them. Some of the popular ones are:
- Styled Components, a library that allows you to create React components with your styling applied, as well as style your components
- CSS Modules, which allows you to import CSS files and generate unique isolated class names to reference the styles
- Emotion, which combines the approaches of Styled Components and CSS Modules into a single library
PropTypes is an optional feature of React that allows you to introduce component runtime prop validation. In contrast to using static type checking with TypeScript, PropTypes will perform type checks when your application is actually running. This comes in especially handy when developing libraries when you can’t be sure your clients are using TypeScript, even if you are. Since React 15.5, prop types have been moved to a separate prop-types library and are now completely optional. Considering its benefits, we advise you to use it to improve the reliability of your application.
React Native is a platform developed by Facebook for creating native mobile applications using React. Unlike Ionic, which produces a hybrid application, React Native produces a truly native UI. It provides a set of standard React components that are bound to their native counterparts. It also allows you to create your components and bind them to native code written in Objective-C, Java, or Swift.
Next.js is a framework for the server-side rendering of React applications. It provides a flexible way to completely or partially render your application on the server, return the result to the client, and continue in the browser. It tries to make the complex task of creating universal applications easier, so the setup is designed to be as simple as possible, with a minimal amount of new primitives and requirements for the structure of your project.
React-admin is a framework for building CRUD-style SPA applications on top of existing REST or GraphQL APIs. It comes with handy features, such as a UI built with Material Design, internationalization, theming, data validation, and more.
UI Development Environments
A major trend in front-end development for the last couple of years has been the boom of development tools that allow you to develop, test, and document your component interactively and separately from the application. Storybook has established itself as one of the leaders in this area, with support for both React and Angular. However, there are other alternatives for React.
React Styleguidist, similarly to Storybook, allows you to create interactive documentation of your components. In contrast to Storybook, the generated UI looks more like an interactive readme than a separate set of stories. While Storybook shines as a development environment, Styleguidist is more a documentation tool.
We’ve also mentioned MDX in this article. It allows you to spice up your Markdown files by adding interactive JSX components.
Testing UI components usually involves having to render them in a sandbox environment, simulate user interaction, and validate the output results. These routine tasks can be simplified by using the appropriate testing helpers. For Angular, this is the built-in TestBed. For React, there are two popular candidates: Enzyme and Testing Library.
Enzyme is the de-facto standard choice. It allows you to render your components into a full or shallow DOM as well as interact with the rendered component. It mostly follows a white box testing approach, where your tests can reference some of the internals of the component like its children components, props, or state.
Testing Library follows a different approach and pushes you to interact with your components as a user would, without knowing the technical implementation. Tests created this way are usually less brittle and easier to maintain. Although it’s most popular with React, the Testing Library is also available for Angular.
Gatsby is a static website generator that uses React.js. It allows you to use GraphQL to query the data for your websites defined in Markdown, YAML, JSON, external APIs, and popular content management systems.
React 360 is a library for creating virtual reality applications for browsers. It provides a declarative React API that’s built on top of the WebGL and WebVR browser APIs, thus making it easier to create 360 VR experiences.
React Developer Tools
React Dev Tools is a browser extension for Chrome for debugging React applications that allows you to traverse the React component tree and see their props and state.
There are plenty of other libraries and tools available in the Awesome React list.
Adoption, Learning Curve and Development Experience
An important criterion for choosing a new technology is how easy it is to learn. Of course, the answer depends on a wide range of factors, such as your previous experience and a general familiarity with the related concepts and patterns. However, we can still try to assess the number of new things you’ll need to learn to get started with a given framework. Now, if we assume that you already know ES6+, build tools, and all of that, let’s see what else you’ll need to understand.
The official tutorial is an excellent place to start learning React. Once you’re done with that, get familiar with the router. The React Router might be slightly complex and unconventional, but nothing to worry about. Depending on the size, complexity, and requirements of your project, you’ll need to find and learn some additional libraries, and this might be the tricky part. But after that, everything should be smooth sailing.
We were genuinely surprised at how easy it was to get started using React. Even people with a back-end development background and limited experience in front-end development were able to catch up quickly. The error messages you might encounter along the way are usually clear and provide explanations on how to resolve the underlying problem.
The downside is that you’ll need to invest time into choosing the libraries to support your development activities. Given how many of them are there, this can pose a challenge. But this can be done along with your development activities after you’ve gotten comfortable with the framework itself.
Although TypeScript is not required for React, we strongly recommend you assess and adopt it in your projects.
The framework itself is rich in topics to learn, starting from basic ones such as modules, dependency injection, decorators, components, services, pipes, templates, and directives, to more advanced topics such as change detection, zones, AoT compilation, and Rx.js. These are all covered in the documentation. Rx.js is a heavy topic on its own and is described in much detail on the official website. While relatively easy to use on a basic level, it gets more complicated when moving on to advanced topics.
All in all, we noticed that the entry barrier for Angular is higher than for React. The sheer number of new concepts may be overwhelming to newcomers. And even after you’ve started, the experience might be a bit rough, since you need to keep in mind things like Rx.js subscription management, change detection performance, and bananas in a box (yes, this is a piece of actual advice from the documentation). We often encountered error messages that are too cryptic to understand, so we had to google them and pray for an exact match.
It might seem that we favor React here, and we definitely do. We’ve had experience onboarding new developers to both Angular and React projects of comparable size and complexity, and somehow with React it always went smoother. But, as I said earlier, this depends on a broad range of factors and might work differently for you.
Popularity and Community Feedback
Both frameworks are highly popular and have communities of followers and advocates. There are also numerous articles suggesting you use one or the other technology, mostly highlighting their positive sides. Let’s see if we can find a more objective way to represent the popularity of each project and developer satisfaction.
The Hacker News Hiring Trends for 2019 lists React as the most wanted technology amongst employees for more than 31 months in a row.
Stack Overflow lists React as the second most popular framework after jQuery. Angular is listed as the third one. Their Most Loved, Dreaded, and Wanted Web Frameworks report paints a similar picture to the others.
The State of Developer Ecosystem 2020 report by Jet Brains confirms React’s position as the most popular front-end framework.
Making a Decision
You might have already noted that each framework has its own set of capabilities, both with their good and bad sides. But this analysis has been done outside of any particular context and thus doesn’t provide an answer on which framework should you choose. To decide on that, you’ll need to review it from the perspective of your project. This is something you’ll need to do on your own.
To get started, try answering these questions about your project and when you do, match the answers against what you’ve learned about the two frameworks. This list might not be complete, but should be enough to get you started:
- How big is the project?
- How long is it going to be maintained?
- Is all of the functionality clearly defined in advance or are you expected to be flexible?
- If all of the features are already defined, what capabilities do you need?
- Are the domain model and business logic complex?
- What platforms are you targeting? Web, mobile, desktop?
- Do you need server-side rendering? Is SEO important?
- Will you be handling a lot of real-time event streams?
- How big is your team?
- How experienced are your developers and what is their background?
- Are there any ready-made component libraries that you would like to use?
If you’re starting a big project and you’d like to minimize the risk of making a bad choice, consider creating a proof-of-concept product first. Pick some of the key features of the projects and try to implement them in a simplistic manner using one of the frameworks. PoCs usually don’t take a lot of time to build, but they’ll give you some valuable personal experience on working with the framework and allow you to validate the key technical requirements. If you’re satisfied with the results, you can continue with full-blown development. If not, failing fast will save you a lot of headaches in the long run.
One Framework to Rule Them All?
Once you’ve picked a framework for one project, you’ll get tempted to use the exact same tech stack for your upcoming projects. Don’t. Even though it’s a good idea to keep your tech stack consistent, don’t blindly use the same approach every time. Before starting each project, take a moment to answer the same questions once more. Maybe for the next project, the answers will be different or the landscape will change. Also, if you have the luxury of doing a small project with a non-familiar tech stack, go for it. Such experiments will provide you with invaluable experience. Keep your mind open and learn from your mistakes. At some point, a certain technology will just feel natural and right.