Two views of the React dashboard (Projects and Results), rebuilt in Angular on the same static JSON API. Types, computations, chart scales, texts and styles are shared: only the framework changes, and the comparison is about it.
Projects view, dark theme: the filters are signals, the list a computed.Results view, light theme: same data and scales as the React dashboard, rendered by Angular components.
Measure
React
Angular
Version
React 19.3.0
Angular 22.2.1
Loaded on opening, compressed
79.7 kB
90.6 kB
Production build (median of 3)
1.4 s
5.2 s
Lines of framework code (the two views and their frame)
499
546
Unit and integration tests
40
11
npm packages installed, tooling included
157
936
Measured by projects/angular/scripts/compare.mjs on 2026-10-07 on Intel(R) Core(TM) i5-10400F CPU @ 2.90GHz. Shared code, counted apart: 582 lines. The React load also covers the Sprints view, without the 3D viewer (loaded on demand); its tests cover its four views; the Angular packages include Jest and Cypress. Both builds check types.
What really changes
State: hooks (useState, useMemo) in React; signals (signal, computed, linkedSignal) in Angular, which recompute only what depends on them, without zone.js.
Data: a home-made hook loads the API in one go in React; one httpResource per file in Angular, with loading, error and reload provided.
Navigation: the URL fragment read by hand in React; Angular's router, with pages loaded on demand and the active link marked by itself.
Tests: Vitest and Testing Library in React; Jest, TestBed and Angular's HTTP testing controller, plus Cypress end to end. A trap of Angular's own, a menu bound before its options, was found and pinned by a test.
Tech stack
Angular
TypeScript
Jest
Cypress
Who does what
Angular
Two dashboard views as standalone signal-based components, without zone.js, with httpResource and the router.
TypeScript
The types, computations and texts shared with the React dashboard.
Jest
Unit tests, and integration tests on the site's real API.