Last year, Angular and React were essentially the same framework, said Google’s Angular lead Minko Gechev during his presentation at this year’s dotJS.
It’s a radical statement in the JavaScript world, where developers are even encouraged to build their own frameworks. After all, Angular uses classes and templates and React uses functions and JSX, he acknowledged. But underneath, they’re serving the same functionality.
“A large chunk of the responsibilities of any frontend framework out there is to keep the model in sync with the view, and that’s where Angular and React used to operate very much the same way,” Gechev said.
Gechev has been charged by Google to do something that he thinks may be a first ever in web development: converge two frameworks; in this case Angular and Wiz, Google’s internal framework. He explained what this means for web developers and the future of frameworks.
Minko Gechev, engineering product lead at Google, with a list of common framework abstractions.
“Converging two different frameworks is something that I haven’t heard of people doing in the past,” he said during the presentation, which became available on YouTube in July. “This allowed me to figure out what a web framework consists of, and [I] see a lot of similarities across frameworks, see how we’re converging on very much the same ideas, and very much sharing the same implementation over time.”
One area where React and Angular were very much the same was in how they keep the component tree in sync with the UI, he said.
“This is often called reactivity or propagation of states over time. That’s where Angular and React were very much the same last year,” he said.
In both cases, developers must specify that the state has changed. In React, that’s done with hooks and in Angular, it’s done with zone.js, he said. But what’s happening is that the frameworks will traverse the component tree, by default, from top to bottom, and find all the differences and apply them to the DOM, he continued.
He provided another example of similarities: An app component that uses two other components — user profile and a shopping cart. The profile component displays a user name, the shopping cart component iterates over a collection of items from a shopping cart. Each displays its quantity.
Code for a shopping cart/Screenshot via YouTube
“Under the hood, once you run your application, the framework is going to build a component tree,” he said. “If we update the state of the cart, let’s say we change the quantity of the first item to be one, both Angular and React are going to perform change detection and reconciliation with very much the same algorithm. They’re going to traverse the component tree, going to the root at first, after that they are going to go to the user profile components.”
If that’s not enough for doubters, Gechev also examined pulled-out benchmarks to show how similar the two were.
Benchmarks for Angular and React
“Both Angular and React are performing pretty poorly for swapping roles, and both frameworks are performing decently well for partial updates,” he said.
Real applications can be different, he added. There can be hundreds or thousands of components that are alive the whole time.
“If we have to traverse these component trees component by component in order to find the differences and reflect these differences in the view, it’s going to take a lot of time,” he said. “So Angular decided to improve its reactivity story.”
Angular introduced static dependency tracking on top of the compiler. They decided to add Signals in Angular 16. Signals are a reactivity primitive; they’re variables that auto-track where they are used. Because of this, Signals are able to invalidate computations that depend on the variable when it changes.
Ember, Solid, Vue, Svelte and others have also deployed Signals. (For more on React and Signals, see Paul Scanlon’s article, “Did Signals Just Land in React”.)
“You can see that all these frameworks are now converging on the same reactivity primitive, Signals,” he said.
Use Cases Converge
Historically, the Wiz framework has been applied to different use cases than Angular, said. It’s more similar to Astro and Qwik, Gechev said.
“It has been serving more consumer applications where performance is specifically critical — we can think Google search or YouTube — and on the other side of the spectrum, Angular has been historically more used for enterprise-like clients, Google Cloud, Google Analytics, and others. However, over time, we noticed that the requirements for these frameworks, they started converging as well.”
“You can see that all these frameworks are now converging on the same reactivity primitive, Signals.” — Minko Gechev, engineering product lead at Google
Signals began the convergence conversation, he said, because the Wiz team wanted to add Signals after seeing it in Angular. And for its part, Angular team members wanted Wiz’s resumability, a concept Wiz introduced 10 years ago and Qwik adopted afterward.
That’s when Gechev was assigned the task of converging the two frameworks.
“Reading through the Google chats of the Wiz team, I saw they had been collaborating with YouTube to re-implement the UI of the platform from their legacy virtual DOM implementation to Signals,” he said. “At the same time, the Angular team was working on integrating Signals as part of the framework. So we decided to team up.”
That led to mobile YouTube using Wiz with Angular Signals, which created significant improvements in performance, he said. For instance, on smart TVs, they saw 35% improvement.
Now there’s a proposal to add Signals to the JavaScript language. Currently, Signals is in stage one, release 39 and the reference implementation uses Angular Signals because it proved that it can work across multiple frameworks.
Convergence Possible in Other Areas
Still, convergence isn’t a trivial task, he cautioned, adding that it could require a lot of changes in frameworks. Stability will also need to be a consideration, he added. But what has given him confidence it can be done is that so far — fingers crossed — the Wiz/Angular convergence hasn’t broken anything in Google internal tests.
“Every time we change something in Angular, we open a pull request, we’re syncing the source code from the pull request to the Google internal mono repo, which has about 4,500 Angular applications there, some of them with millions of lines of code,” he said. “We’re running the tests for all the affected applications to make sure that nothing changed, nothing broke. This means a lot of pain for us, debugging, all these tests, code that we’ve never seen before. But it also guarantees an unmatched backward compatibility.”
“When picking a framework, don’t overthink it. It will end up being the same technology anyway with a different facade.” — Gechev
He predicted that there would also be a possibility of convergence on event replay and fine grain code loading, by which he said he meant partial hydration or the island architecture for which Astro has advocated. Event replay is how Google solves the interactivity gap between a user seeing the structure of their web app and being able to interact with it. Currently, the team is working to modernize a library called JS Action or Event Dispatch, which it will then move into the Angular mono repo.
“It is the same code that powers the event replay in Google search, it is on github.com/angular/angular,” Gechev said. “We added supports in the developer preview for Angular. You can enable it by using provide client hydration, specifying the width event replay feature. There is another opportunity to improve performance.
“Now we can shrink this time needed for downloading the JavaScript and executing it by serving less JavaScript, which has been achieved with resumability, or with some fancy partial hydration, where we implicitly specify what is the minimum code required to handle a particular user interaction.”
Introducing Deferrable Views
That allows the application to download only the minimum amount of code required to respond to a certain user interaction, rather than downloading the whole application, he explained. That can’t be done in Angular in the same implicit way because it will break a lot of applications and it doesn’t really fit the paradigm that developers are using Angular with today, he said.
Deferrable views code
To address that gap, they introduced deferrable views, which allow developers to create interactivity or hydration islands in an application.
“With the deferrable views, you can wrap part of your UI inside of a block and specify that you want this block to be hydrated only when a particular condition is met,” he explained. “This is the semantics when using server-side rendering.”
When a request from the client is sent to the server, it provides the markup of the application Ahead of time, developers will have created different interactivity islands with these different blocks, he said.
Deferrable views on mobile design.
So if user interaction is the hydration trigger, when the user interacts with, for example, the left navigation bar, it can download the corresponding JavaScript from the server and hydrate that part of the app without downloading any of the remaining functionality.
“We can download the minimal amount of JavaScript required to handle this particular user interact,” he said. “And with event replay, we can replay the event also so that we don’t lose any clicks.”
Angular Implications
This raises the question: What does this mean for Angular and web developers?
“How is this going to manifest to web developers? In practice, this is going to be just gradual improvements that we’re introducing to Angular over time,” Gechev told the audience. “In the process, we’ll be seeking opportunities to open source primitives that are established as best practices in the industry.”
Some may think there are too many differences for convergence, he acknowledged. For example, React has no dependency injection and Angular doesn’t have a context API, he said. But underneath they both serve the same purpose.
“In both cases, we want to inject data in our components based on the context in which they’re used,” he said. “In Angular, we do that with dependency injections. In React, we do that with the context API. They seem to serve the same purpose but they have a slightly different look. They also share very much the same data structures.”
The Developer Takeaway
Addy Osmani, the lead engineer for Chrome, had published a table from a web developer perspective that shows features available in each individual framework, which he shared at Google I/O 2024. Gechev modified the table to reflect his own view that frameworks are converging on the same features.
Table showing abstractions across JavaScript frameworks.
“What does that mean for web developers? How do you even pick a framework nowadays?” Gechev said. “When picking a framework, don’t overthink it. It will end up being the same technology anyway with a different facade.”
That said, he did offer a couple of pointers that are sometimes overlooked when choosing a technology. He advised web developers to consider stability and reliability.
“We want to make sure that we’re using a stable solution that is going to be with you over the long run,” he said. “And it’s really important to have also a rich ecosystem that is inclusive and supportive of you and something that you really enjoy using.”
TRENDING STORIES
YOUTUBE.COM/THENEWSTACK
Tech moves fast, don't miss an episode. Subscribe to our YouTube channel to stream all our podcasts, interviews, demos, and more.
Loraine Lawson is a veteran technology reporter who has covered technology issues from data integration to security for 25 years. Before joining The New Stack, she served as the editor of the banking technology site Bank Automation News. She has...