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()withEventEmitter
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