All insights

Practice

How I Audit an Existing Angular Codebase

Before refactoring an inherited Angular application, understand where its real cost lives. Measure the application, architecture, history and runtime behaviour before proposing changes.

Angular codebase audit combining runtime behaviour, architecture, Git history, network and bundle evidence into a prioritized plan.

Most inherited Angular applications arrive with a symptom: the application feels slow, features take too long to build, one area is difficult to change, or the team believes the architecture needs modernization.

The expensive mistake is treating the reported symptom as the diagnosis. Before recommending a rewrite, state-management change or Angular upgrade, I first establish where the actual cost is.

Step 1: run the Angular application before reading the code

A slow Angular application split into network, change detection, bundle and rendering evidence rather than guessed fixes.
“The app feels slow” is a symptom. Measuring each category first is what turns it into a diagnosis.

Use the product like a user before opening the architecture. Test representative workflows on realistic hardware and network conditions while keeping browser performance and network tools visible.

This quickly exposes repeated requests, delayed interactions, unexpected layout shifts and workflow friction that developers working in the application every day may have learned to ignore.

Step 2: measure the shape of the Angular codebase

Early auditing should focus on structural facts rather than subjective quality judgments.

A small set of searches can quickly map Angular architecture and state-management patterns.
# NgModules and standalone components rg -c "@NgModule" src --type ts rg -c "standalone: true" src --type ts # RxJS state and Signals rg -n  "BehaviorSubject|new Subject"  src --type ts rg -n  "signal\(|computed\("  src --type ts # Store usage rg -l  "StoreModule|createReducer|createEffect"  src --type ts # Manual change detection rg -n  "detectChanges\(\)"  src --type ts

These numbers do not tell you whether the code is good or bad. They tell you where architectural decisions live and which areas deserve closer inspection.

Step 3: use Git history to find expensive Angular files

Angular codebase structure and architectural patterns beside Git change frequency and hotspot analysis per file.
Complexity only costs you where the file also changes often — that intersection is the hotspot.

A complicated file that has not changed for two years may create less practical cost than a moderately complicated component modified in almost every release.

Find Angular files that change most frequently and compare that with size and complexity.
git log  --since="1 year ago"  --name-only  --pretty=format:  | rg "^src/.*\.(ts|html)$"  | sort  | uniq -c  | sort -rn  | head -25

Step 4: ask the team what broke recently

Production history is another architectural signal. Ask what last failed in production, which recent change took much longer than expected and which area developers avoid touching.

Those answers often reveal coupling and ownership problems that static analysis cannot show.

Step 5: separate Angular performance problems

Do not treat “the application is slow” as one category. Network duplication, change detection, initial bundle cost and rendering pressure need different evidence and different fixes.

Use production build statistics and profiling tools to eliminate performance causes systematically.
ng build  --configuration production  --stats-json npx source-map-explorer  dist/**/*.js rg -L  "ChangeDetectionStrategy.OnPush"  src  --type ts  -g "*.component.ts"

Then inspect the network waterfall for duplicate and unnecessarily serial requests. A performance recommendation should name the bottleneck rather than simply list every optimization Angular supports.

Turn the Angular audit into a prioritized plan

Angular audit findings scored by cost, risk, change frequency and effort, then split into act now, plan and leave alone.
The output is not a list of everything imperfect, but an ordered list of what is worth changing next.

The useful output of an audit is a written plan. Each finding should explain what is happening, what it costs today, what changing it requires, what dependencies exist and approximately how large the work is.

A good audit should also identify code that looks imperfect but is not worth changing. Technical debt only deserves priority when it creates measurable risk, performance cost or development friction.

The final test is whether the team can act on the report without the person who wrote it. If the recommendations are specific, evidence-based and ordered correctly, the assessment remains useful even if another developer performs the implementation.

Sources

Where this is applied

Keep reading