Angular Smart vs Dumb Components

Learn Smart (Container) Components vs Dumb (Presentational) Components in Angular with architecture diagrams, best practices, Signals, NgRx integration, real-world examples, and interview questions.

One of the most important architectural concepts in Angular is separating components based on responsibility.

Instead of placing all logic inside every component, Angular applications typically divide components into:

  • Smart Components (Container Components)
  • Dumb Components (Presentational Components)

This separation improves:

  • Reusability
  • Testability
  • Maintainability
  • Scalability

This topic is frequently discussed in Senior Angular Developer, Lead Developer, and Angular Architect interviews.


Table of Contents

  • What are Smart and Dumb Components?
  • Why Separate Responsibilities?
  • Smart Components
  • Dumb Components
  • Communication Flow
  • Architecture
  • Angular Signals
  • NgRx Integration
  • Best Practices
  • Common Mistakes
  • Top 10 Interview Questions
  • Summary

What are Smart and Dumb Components?

Angular components can be classified based on their responsibilities.

Component Type Responsibility
Smart Component Business logic, state management, API calls
Dumb Component Display UI and emit user actions

High-Level Architecture

flowchart TD

API

API --> SmartComponent

SmartComponent --> Service

Service --> SmartComponent

SmartComponent -->|"@Input()"| DumbComponent

DumbComponent -->|"@Output()"| SmartComponent

SmartComponent --> Browser

Why Separate Components?

Without separation, components become:

  • Difficult to maintain
  • Difficult to reuse
  • Hard to test
  • Large and complex

With separation:

  • UI becomes reusable
  • Business logic stays centralized
  • Components become easier to understand
  • Teams can work independently

Traditional Monolithic Component

flowchart TD

Component

Component --> API

Component --> BusinessLogic

Component --> UI

Component --> Validation

Component --> StateManagement

Component --> EventHandling

Problems:

  • Too much responsibility
  • Hard to debug
  • Tight coupling
  • Large files

Smart Component (Container Component)

A Smart Component is responsible for:

  • Calling APIs
  • Managing state
  • Handling routing
  • Coordinating child components
  • Dependency Injection
  • Business logic

Think of it as the controller of the UI.


Smart Component Responsibilities

flowchart LR

SmartComponent

SmartComponent --> API

SmartComponent --> Service

SmartComponent --> Router

SmartComponent --> Signals

SmartComponent --> Store

SmartComponent --> ChildComponents

Smart Component Example

@Component({
    selector:'app-products',
    standalone:true,
    imports:[ProductListComponent],
    template:`

      <app-product-list

      [products]="products"

      (selected)="viewProduct($event)">

      </app-product-list>

    `
})
export class ProductsComponent{

products:Product[]=[];

constructor(

private service:ProductService

){}

ngOnInit(){

this.service.getProducts()

.subscribe(data=>{

this.products=data;

});

}

viewProduct(product:Product){

console.log(product);

}

}

Responsibilities of Smart Components

  • Fetch data
  • Save data
  • Update state
  • Handle navigation
  • Handle authentication
  • Coordinate child components
  • Handle errors

Dumb Component (Presentational Component)

A Dumb Component focuses only on presentation.

Responsibilities:

  • Display UI
  • Receive Inputs
  • Emit Outputs
  • No API calls
  • No business logic

Dumb Component Architecture

flowchart LR

InputData

InputData --> DumbComponent

DumbComponent --> UI

UserClick --> OutputEvent

OutputEvent --> Parent

Dumb Component Example

@Component({
selector:'app-product-list',
standalone:true,
template:`

<div

*ngFor="let product of products">

<button

(click)="select(product)">

{{product.name}}

</button>

</div>

`
})
export class ProductListComponent{

@Input()

products:Product[]=[];

@Output()

selected=

new EventEmitter<Product>();

select(product:Product){

this.selected.emit(product);

}

}

Notice:

  • No HTTP call
  • No service
  • No routing
  • Only UI

Communication Flow

sequenceDiagram

participant Smart

participant Service

participant API

participant Dumb

Smart->>Service: Fetch Products

Service->>API: HTTP Request

API-->>Service: Products

Service-->>Smart: Data

Smart->>Dumb: @Input()

User->>Dumb: Click Button

Dumb->>Smart: @Output()

Real-World Banking Example

Imagine an online banking application.

flowchart TD

BankAPI

BankAPI --> DashboardComponent

DashboardComponent --> AccountCard

DashboardComponent --> BalanceCard

DashboardComponent --> LoanCard

DashboardComponent --> InvestmentCard

Smart Component

DashboardComponent:

  • Loads account balances
  • Calls APIs
  • Refreshes data
  • Handles authentication
  • Updates Signals

Dumb Components

AccountCard:

  • Shows account balance

LoanCard:

  • Displays loan details

InvestmentCard:

  • Displays investments

None of these components call APIs directly.


Folder Structure

app/

├── dashboard/

│   ├── dashboard.component.ts   (Smart)

│   ├── dashboard.service.ts

│   ├── account-card.component.ts

│   ├── balance-card.component.ts

│   ├── investment-card.component.ts

│   └── loan-card.component.ts

Smart vs Dumb Comparison

Feature Smart Component Dumb Component
API Calls ✅ Yes ❌ No
Business Logic ✅ Yes ❌ No
Routing ✅ Yes ❌ No
Dependency Injection ✅ Yes Minimal
State Management ✅ Yes ❌ No
UI Rendering ✅ Yes ✅ Yes
Inputs Yes Yes
Outputs Yes Yes
Reusability Medium Very High
Unit Testing Medium Easy

Angular Signals Example

Modern Angular encourages Signals for local state.

import { signal } from '@angular/core';

export class DashboardComponent{

accounts = signal<Account[]>([]);

loading = signal(false);

}

Pass data

<app-account-card

[accounts]="accounts()">

</app-account-card>

The Dumb Component remains unaware of Signals—it simply receives data through @Input().


NgRx Architecture

Large enterprise applications often use NgRx.

flowchart LR

Store

Store --> SmartComponent

SmartComponent --> DumbComponent

DumbComponent --> Action

Action --> Store

Flow:

  • Store provides state
  • Smart Component selects state
  • Dumb Component renders UI
  • User action emits an event
  • Smart Component dispatches an action

Benefits of Smart/Dumb Architecture

  • Clear separation of concerns
  • Smaller components
  • Reusable UI
  • Easier testing
  • Better scalability
  • Predictable communication
  • Cleaner codebase

Common Mistakes

❌ API calls inside every component

❌ Business logic in templates

❌ Child components modifying application state

❌ Direct communication between sibling components

❌ Components exceeding 1,000 lines of code

❌ Duplicating UI logic


Best Practices

  • Keep Smart Components small.
  • Keep Dumb Components reusable.
  • Use @Input() for data.
  • Use @Output() for events.
  • Move API calls into services.
  • Use Signals or NgRx for state management.
  • Avoid business logic inside templates.
  • Write focused unit tests for both component types.

Enterprise Architecture

flowchart TD

Browser

Browser --> SmartComponent

SmartComponent --> Service

Service --> RESTAPI

SmartComponent --> Store

Store --> SmartComponent

SmartComponent --> DumbComponentA

SmartComponent --> DumbComponentB

SmartComponent --> DumbComponentC

DumbComponentA --> User

DumbComponentB --> User

DumbComponentC --> User

When to Use Each Component Type

Scenario Smart Dumb
Dashboard
Product Card
Login Form Partial
Shopping Cart Page
Button Component
Header Badge
Profile Page
Chart Widget Partial

Advantages

Smart Components Dumb Components
Centralized logic Highly reusable
Easy state management Easy testing
Better orchestration Small components
Coordinates children Focused UI
Handles APIs Minimal dependencies

Top 10 Angular Smart vs Dumb Components Interview Questions

1. What is a Smart Component?

Answer

A Smart Component (Container Component) manages application state, calls services, handles routing, coordinates child components, and contains business logic.


2. What is a Dumb Component?

Answer

A Dumb Component (Presentational Component) focuses only on rendering the UI. It receives data through @Input() and communicates user actions through @Output().


3. Why separate Smart and Dumb Components?

Answer

Separating responsibilities improves maintainability, reusability, testability, scalability, and readability. It also reduces coupling between business logic and presentation.


4. Should a Dumb Component call an API?

Answer

No. API calls should be handled by Smart Components or services. Dumb Components should remain focused on presentation.


5. Can a Smart Component contain UI?

Answer

Yes. Smart Components often render layouts and orchestrate child components, but most detailed UI should be delegated to Dumb Components.


6. How do Smart and Dumb Components communicate?

Answer

  • Smart → Dumb: @Input()
  • Dumb → Smart: @Output() with EventEmitter

7. How do Signals fit into this architecture?

Answer

Smart Components typically own Signals for state management. They pass signal values to Dumb Components through @Input(), keeping presentation components framework-agnostic.


8. How does NgRx work with Smart and Dumb Components?

Answer

Smart Components interact with the NgRx Store by selecting state and dispatching actions. Dumb Components display the selected data and emit events back to the Smart Component.


9. Are Smart and Dumb Components mandatory in Angular?

Answer

No. Angular does not enforce this pattern, but it is a widely adopted architectural guideline for medium and large applications because it improves maintainability.


10. What are the best practices for Smart and Dumb Components?

Answer

  • Keep business logic in Smart Components.
  • Keep presentation logic in Dumb Components.
  • Use services for API communication.
  • Use @Input() and @Output() for communication.
  • Prefer Signals or NgRx for state management.
  • Make Dumb Components reusable and independent.

Interview Cheat Sheet

Topic Remember
Smart Component Business Logic
Dumb Component UI Only
API Calls Smart
State Management Smart
@Input() Smart → Dumb
@Output() Dumb → Smart
Signals Smart owns state
NgRx Smart connects to Store
Reusability Dumb Components
Enterprise Pattern Smart + Dumb Architecture

Summary

The Smart vs Dumb Component pattern is a proven architectural approach for building scalable Angular applications. Smart Components manage business logic, application state, routing, and API interactions, while Dumb Components focus exclusively on rendering data and emitting user interactions. By separating responsibilities and using @Input() and @Output() for communication, developers can create applications that are easier to maintain, test, and extend. Combined with modern Angular features such as Signals and state management libraries like NgRx, this pattern remains a cornerstone of enterprise Angular development.


Key Takeaways

  • ✔ Smart Components manage state and business logic.
  • ✔ Dumb Components focus on presentation.
  • ✔ Communicate using @Input() and @Output().
  • ✔ Keep API calls in services or Smart Components.
  • ✔ Use Signals or NgRx for scalable state management.
  • ✔ Build reusable UI with Dumb Components.
  • ✔ This architecture is widely used in enterprise Angular applications.

Next Article

➡️ 20-Angular-Data-Binding-QA.md