To compare React with Angular I use the projects ReactAndGo and MovieManager.
The frontend of the MovieManager project uses the Ng-Bootstrap components, the Angular Router and uses Angular Internationalization for translation.
The frontend of the ReactAndGo project uses Mui components, the React-Router and uses React-I18next for translation. For global state Jotai is used.
Create the frontend
With Angular the frontend can be created with the cli: ng new application-name –routing=true
With React the frontend can be created with the react-router cli: npx create-react-router@latest
Use Component libraries
With Angular the Ng-Bootstrap component library is used.
With React the Mui component library is used.
In the React components this import is needed: “import * as React from ‘react’;” To use the components without namespace.
Use Routing
With Angular the routes are defined like this:
const routes: Routes = [
{ path: "search", component: SearchComponent },
{ path: "movie/:id", component: MoviesComponent },
...
];
@NgModule({
imports: [RouterModule.forRoot(routes, {})],
exports: [RouterModule],
})
export class AppRoutingModule {}
With React the routes are defined like this:
export default [
index("routes/home.tsx"),
route("app/app", "routes/app.tsx"),
] satisfies RouteConfig;
Use Translation
With Angular Internantionalization is used for translation. It creates a bundle for each language and optimizes for performance. The translations are stored in a Json key value file. With the Transloco library, translation at runtime can be used with a pretty similar Json key value file.
Using the translation looks like this:
<span i18n="@@loading">Loading</span>
With React the React-I18nnext library is used. It does translation at runtime and stores the translation in a Json key value file.
Using the translation looks like this:
<MenuItem value={'en'}>{t('common.english')}</MenuItem>
Use Global State
Angular can use for global state its services:
@Injectable()
export class TokenService {
private myToken!: string;
...
}
React can use for global state the Jotai library:
const GlobalState = {
userNameState: atom(''),
...
}
export default GlobalState;
This state can then be used in the components:
export function Login() {
const [globalUserName,setGlobalUserName] =
useAtom(GlobalState.userNameState);
...
}
Use Rest Calls to the backend
Angular uses its Services:
@Injectable({
providedIn: "root",
})
export class MoviesService {
constructor(private http: HttpClient) {}
public findMovieByTitle(title: string): Observable<Movie[]> {
if (!title) {
return of([]);
}
return this.http
.get<Movie[]>("/rest/movie/" + encodeURIComponent(title))
...
);
}
}
React can use the Fetch Api in an api file:
const apiPrefix = '/api';
async function handleResponse<T>(response: Response,navigate: NavigateFunction): Promise<T> {
if (!response.ok) {
const error = await response.text();
if(navigate) navigate('/');
throw new Error(error || `HTTP error! status: ${response.status}`);
}
return response.json();
}
Bundle size
The Angular initially loaded bundle size over 100k.
The React initial loaded bundle size is over 100k.
The two applications are different so a direct comparison is not useful. What can be said is that React and Angular frontends in the same complexity category have pretty similar initially loaded bundle sizes.
Conclusion
For frontends of medium or large size React and Angular can be both used. The differences are in the philosophy of both ecosystems.
Angular is an integrated framework that is prepackaged and provides a lot of functionality out of the box. For non trivial use cases most of the functionality is needed.
React is a library with an ecosystem of libraries around it. The needed libraries need to be chosen and integrated in a frontend. For non trivial use cases several other libraries are needed. That gives you more freedom but also more responsibility because libraries can be loose support.
One difference worth mentioning is that Angular has strict type checking. React has typescript support but the type checking is less comprehensive. For people who are used to compile time type checking that makes error search easier.