"If you are still on #Angular, it might be time to think about having a look at #React"
One day after, Marco replied and cited a part of the article which said:
"React, on the other hand, still needs a lot of additional decisions for routing and data management libraries. This can be very intimidating for beginners and makes it difficult to get started working with the framework. Angular, Ember and Vue, on the other hand, all have the 'all inclusive' advantage that React lacks."
Additionally he asked:
"What are your thoughts about this part of the interview? How do you handle this for new projects with React? Different setups depending on the needs? One setup fits all? Would love to hear your best practices."
We then decided to discuss this via email, and to blog about our findings eventually. Now, a few months have passed, and I finally found the time to write the first post.
Comparing apples and oranges
Basically, comparing React and Angular doesn't make sense. While React is a library focused on a single task (rendering the UI), Angular is a framework which provides a full-featured solution that contains everything you need to setup a UI.
This automatically means that Angular tries to follow a one size fits all approach, while React forces you to combine it with other modules to have a setup for your UI. Both approaches have their advantages and their disadvantages.
Angular is fine as long as you agree with its decision and strictly follow its predefined paths. React, in contrast, gives you way more freedom and flexibility, but the price is to have to think and plan much more for it.
Nevertheless, although both are heading into completely different directions, most developers don't decide for one or the other based on whether they prefer a library or a framework, or on the fact whether they have to add a few more modules or not. Actually, they decide based on something they are not even aware of. They decide based on the underlying paradigm.
What does that mean? To understand this, we have to take a step back and talk about object-oriented and functional programming.
On object-oriented programming
If one takes classical object-oriented programming seriously, objects serve to reflect the application domain. They represent business processes. This means that on the one hand they encapsulate all data relevant to a business process and on the other hand they have the logic to work with this data. If one takes the object-oriented paradigm seriously, this means primarily dealing with the analysis and modelling of domains.
In reality, however, what is usually discussed is rather technical. In the worst case, these discussions are determined by object-oriented, technical peculiarities of the respective programming language. However, software development is not an end in itself, but is about solving real-world problems! Nowadays, this way of thinking can only be found in the field of domain-driven design.
Object-orientation is thus misunderstood and therefore usually incorrectly applied. Of course, object-oriented programming can then no longer fulfil its promises such as abstraction and reusability, which leads to contempt. That's one problem.
The other problem is indeed a technical one. In the 1990s, the speed of processors increased steadily. If a software ran too slowly, you could simply wait for the next hardware generation to solve the problem. But these times are over: processors are no longer getting faster, instead their number (or at least the number of their cores) is increasing.
However, software does not automatically benefit from more processors. In order to take advantage of the increased performance, it must be able to parallelize tasks. While the simultaneous reading of data is unproblematic, this does not apply to writing. This leads to race conditions and other timing problems that are difficult to get under control.
It is no coincidence that almost every object-oriented programming language offers special keywords to synchronize or lock simultaneous access to data. This makes the design and development of objects time-consuming and error-prone.
This contradicts the desire to obtain simple and error-free code whose effects can be predicted without depending on chance or other temporal effects at runtime. And this is exactly what works much better with functional programming.
On functional programming
A wonderful example for this is the immutability of objects. The basic idea is that an object cannot be changed. Instead, each change creates a new instance. This means that there are no competing write accesses, so there can be no such problems like data races. Each instance then represents a single unchangeable state.
In addition, every change becomes clear because a function call returns a new instance. You know that the object still has the same state after a function call, and that the new state is included in the return value. This makes thinking about the code and its effects much easier.
The sequence of the code also shows which function calls are interdependent and which are not. This information can be determined not only by humans, but also by the compiler – and correspondingly, it can generate parallel code for all those function calls that are independent of each other.
Ironically, all this is nothing new. Such considerations already existed in the 1950s within the programming language Lisp, from which one can learn an enormous amount, especially with regard to these fundamental concepts of data structures and processes.
Much of this is or was taken up in React. So, conceptually speaking, React is not as new as many initially believe. React's great achievement, however, is to make the concepts and methods of functional programming easily understandable and to promote their dissemination. If you are familiar with functional programming and its concepts, you will find a lot of familiar things in React. This was also already pointed out by René Viering in the interview On React.
A question of values
In other words, if you want to program a UI according to the functional way, it will be difficult to find a better solution than React, because React is an excellent implementation of the functional paradigm. That's why other libraries and frameworks are finding it increasingly difficult to prevail against React: It is difficult to implement the underlying paradigm in a better way.
And now, the very same applies to Angular, except that it is the object-oriented rather than the functional programming that can be considered the fundamental paradigm. If you want to program a UI in the object-oriented way, it will be difficult to find a better framework than Angular – again because Angular is simply an excellent implementation of the underlying paradigm.
The question of React or Angular is therefore less a question of the respective technology, but ultimately of the underlying concepts and convictions: Do you prefer the functional paradigm or rather the object-oriented one? The environment you prefer depends heavily on this.
By the way, the same applies to TypeScript. The language implements the concept of an object-oriented programming language based on a static type system quite well. That's why so many companies use it, if they have been using C# and Java before. TypeScript provides developers with what they are used to and that makes them feel comfortable.
Selecting a paradigm
Ultimately, however, every developer has to find the answer to these questions for themselves and evaluate individually how important the aforementioned aspects are.
So, in the end, I guess I still haven't answered Marco's question about my best practices with React. But I hope that I at least could lay the foundation for the next part of our discussion, and that I could explain in a reasonable and understandable way why I decided to go with React rather than Angular.