← Back to list

Why HTML Can Destroy Your Angular Architecture

The Hidden Cost of Fat Templates

Dipak Ahirav in Angular Engineering · 2026-07-04 01:43 · 53 claps · 3.9 min read paywalled
#angular #software-architecture #software-engineering #architecture #frontend-architecture
Open on Medium ↗
Wiki topics: 🌐 · Web Development 🏛️ · Architecture

Why HTML Can Destroy Your Angular Architecture

The Hidden Cost of Fat Templates

Your Angular components aren’t always the problem. Sometimes your HTML template is where architectural complexity quietly begins. Learn why enterprise Angular teams keep templates thin, move business decisions into the right layers, and build applications that remain readable, scalable, and maintainable as they grow.

Your Component Looks Small… But Is It Really?

One of the most common compliments developers give an Angular project is:

“The component is only 150 lines.”

That sounds great.

Until you open the HTML template.

Suddenly you find hundreds of lines of nested conditions, complex bindings, multiple structural directives, permission checks, business rules, and long expressions spread throughout the markup.

The TypeScript file looks clean.

The architecture isn’t.

Many Angular teams spend years trying to reduce component complexity while unknowingly moving that complexity into the template.

The component becomes thinner.

The template becomes the new source of technical debt.

**Not a Member? Read for FREE here.**

HTML Was Never Designed to Hold Business Logic

Angular templates exist for one purpose:

Describe the user interface.

They should answer questions like:

  • What should the user see?
  • Which component should render?
  • Which value should be displayed?
  • Which event should be triggered?

Templates should not decide:

  • Whether a customer is eligible for a discount
  • Whether an order can be approved
  • Which workflow should execute
  • Whether a user satisfies multiple business rules
  • Complex permission calculations

When templates start making business decisions, architecture begins to blur.

It Starts Innocently

Almost every Angular application begins with something simple.

<button *ngIf="isLoggedIn">
  Save
</button>

Nothing wrong here.

Then requirements grow.

<button
  *ngIf="
    isLoggedIn &&
    customer.status === 'ACTIVE' &&
    hasPermission('EDIT') &&
    !loading &&
    featureEnabled &&
    customer.orders.length > 0
  "
>
  Save
</button>

Still works.

Then another condition.

Then another.

Eventually your template contains more business logic than your TypeScript.

The Template Slowly Becomes the Application

Enterprise Angular projects often contain templates like this:

@if (
    customer &&
    permissions.canEdit &&
    featureFlags.orders &&
    !loading &&
    hasOutstandingInvoices(customer) &&
    customer.accountStatus === 'ACTIVE'
) {
    <app-order-summary />
}

Nothing here breaks Angular.

Nothing throws an error.

But architecture is quietly changing.

The HTML is no longer describing the interface.

It’s describing business rules.

Why Fat Templates Become Expensive

Large templates introduce several long-term problems.

1. They are difficult to read

Developers spend more time understanding conditions than understanding the UI.

2. They hide business rules

Important business decisions become scattered across dozens of template expressions.

3. They are difficult to test

Testing complex template behavior often requires reproducing multiple application states.

4. Code reviews become harder

Instead of reviewing architecture, reviewers spend time deciphering long HTML expressions.

5. Designers avoid touching templates

Even simple UI changes become risky because nobody wants to accidentally break complicated conditions.

Components Should Prepare Data

Instead of asking the template to calculate everything…

Prepare the data first.

Bad:

<button
*ngIf="
customer.orders.length > 0 &&
customer.isVerified &&
permissions.canEdit &&
!loading
">
Save
</button>

Better:

readonly canSave = computed(() =>
  customer().orders.length > 0 &&
  customer().isVerified &&
  permissions.canEdit() &&
  !loading()
);

Then your template becomes:

<button *ngIf="canSave()">
  Save
</button>

The HTML immediately becomes easier to understand.

Signals Make Thin Templates Easy

Modern Angular provides an excellent solution.

Instead of placing calculations inside HTML, move them into computed Signals.

Example:

readonly canDisplayPremiumBanner = computed(() =>
  currentUser().subscription === 'PREMIUM' &&
  !maintenanceMode() &&
  featureFlags().premiumBanner
);

Template:

@if (canDisplayPremiumBanner()) {
    <app-premium-banner />
}

The template now describes the UI.

The business decision lives in TypeScript where it belongs.

Build a View Model

Another enterprise pattern is creating a ViewModel.

Instead of exposing dozens of individual values:

customer
permissions
loading
featureFlags

Expose one object prepared specifically for the UI.

readonly vm = computed(() => ({
    customer: customer(),
    canSave: canSave(),
    showAnalytics: showAnalytics(),
    isEditable: isEditable()
}));

Template:

@if (vm().canSave) {
    <button>Save</button>
}

Simple.

Readable.

Maintainable.

Your HTML Should Be Predictable

A healthy Angular template should mostly contain:

  • Components
  • Inputs
  • Outputs
  • Structural directives
  • Simple bindings

Not:

  • Permission calculations
  • Pricing logic
  • Inventory checks
  • Approval workflows
  • Business policies

If business knowledge exists inside HTML, it probably belongs elsewhere.

A Good Code Review Question

Whenever you review a template, ask:

Is this HTML describing the interface or describing the business?

If the answer is:

“The business.”

The logic probably belongs in:

  • Computed Signals
  • ViewModel
  • Facade
  • Feature Service
  • Workflow
  • Domain Service

A Practical Checklist

Before adding another condition to your template, ask yourself:

  • Can this become a computed Signal?
  • Should this belong in a ViewModel?
  • Is this presentation logic?
  • Is this business logic?
  • Will another developer understand this in six months?

If the answer is no, reconsider where the logic lives.

Final Thoughts

Fat templates don’t happen overnight.

They grow one condition at a time.

One extra *ngIf.

One more permission check.

One additional ternary operator.

Eventually the HTML becomes more complicated than the component itself.

Great Angular architecture isn’t about making templates clever.

It’s about making them obvious.

The best enterprise Angular templates are surprisingly simple.

Because they focus on one responsibility:

Describing the user interface.

Everything else belongs somewhere better.

[embed]The Hidden Cost of Global State: Why Everything Doesn’t Belong in Your Store One Store To Rule Them Allmedium.com

Connect with Me

If you enjoyed this post and would like to stay updated with more content like this, feel free to connect with me on social media:

Email: Email me on dipaksahirav@gmail.com for any questions, collaborations, or just to say hi!

I appreciate your support and look forward to connecting with you!


메타데이터
post_id
5758ee3fd7ea
slug
why-html-can-destroy-your-angular-architecture-5758ee3fd7ea
url
https://medium.com/angular-engineering/why-html-can-destroy-your-angular-architecture-5758ee3fd7ea
canonical_url
https://medium.com/angular-engineering/why-html-can-destroy-your-angular-architecture-5758ee3fd7ea
author_url
https://medium.com/@dipaksahirav
status
ok
fetched_at
2026-07-09 03:40:04