The addition of Standalone Components has been one of the most significant advancements in Angular's evolution over the years. By decreasing boilerplate and increasing the self-containedness and reusability of components, this feature streamlines application architecture.
Using a real-time shop application sample that I created locally, I will describe independent components, how they differ from ordinary (module-based) components, and when not to use them.

What is a Standalone Component?
A Standalone Component is an Angular component that does not need to be declared inside an NgModule.
Instead of relying on modules for declarations and imports, a standalone component directly manages its own dependencies.
In traditional Angular applications:
- Every component must be declared in an NgModule
- Routing, directives, and pipes are imported via modules
With standalone components:
- Components are self-contained
- Dependencies like CommonModule, RouterLink, or other components are imported directly in the component decorator
- Applications become simpler, more readable, and easier to maintain
Angular now recommends standalone components for new applications, making them the future-proof approach.
Real-Time Scenario: Store Application Using Standalone Components
To understand standalone components in practice, I created a simple store application with the following pages:
- Landing Page
- Products Page
- Product Details Page
- Services Page
- About Us Page
- Contact Us Page
Almost all components in this application are standalone, including routing and navigation.
Routing Without Modules (app.routes.ts)
Instead of defining routes inside a routing module, routes are configured directly using standalone components:
export const routes: Routes = [
{ path: '', component: LandingComponent },
{ path: 'about', component: AboutComponent },
{ path: 'products', component: ProductListComponent },
{ path: 'products/:id', component: ProductDetailComponent },
{ path: 'services', component: ServicesComponent },
{
path: 'contact',
loadComponent: () =>
import('./contact/contact.component').then(m => m.ContactComponent)
},
];
Why this matters
- No routing module required
- Supports lazy loading at component level
- Cleaner and more readable route definitions
Root Component as a Standalone Component
The root component (AppComponent) itself is standalone and imports only what it needs:
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, NavbarComponent],
templateUrl: './app.component.html',
styleUrl: './app.component.scss'
})
export class AppComponent {
title = 'Standalone_Component_POC';
}
Key Takeaways
RouterOutlet and NavbarComponent are imported directly
No AppModule is required
The root component controls its own dependencies
Navbar as a Reusable Standalone Component
The navigation bar is a perfect example of a reusable standalone component:
@Component({
selector: 'app-navbar',
standalone: true,
imports: [RouterLink, RouterLinkActive],
templateUrl: './navbar.component.html',
})
export class NavbarComponent {}
Benefits
- Can be reused across multiple pages
- No shared module needed
- Easy to move or refactor
Product Listing Page Using Standalone Component
The products page displays a list of products and uses routing for navigation:
@Component({
selector: 'app-product-list',
standalone: true,
imports: [CommonModule, RouterLink],
templateUrl: './product-list.component.html'
})
export class ProductListComponent {
products = [
{ id: 1, name: 'Red T-Shirt', price: 19.99 },
{ id: 2, name: 'Blue Jeans', price: 49.99 },
{ id: 3, name: 'Sneakers', price: 89.99 },
];
}
What this demonstrates
CommonModule is imported directly for structural directives
RouterLink is imported at component level
The component is fully independent and reusable
Lazy-Loaded Contact Page
The Contact page is lazy-loaded using loadComponent, which avoids loading it upfront:
@Component({
selector: 'app-contact',
standalone: true,
imports: [CommonModule],
templateUrl: './contact.component.html',
})
export class ContactComponent {}
Why this is powerful
- Reduces initial bundle size
- Improves application performance
- No feature module required for lazy loading
UI Screenshots of the Store Application Built Using Standalone Components
Landing Page – Standalone Component Entry Point
Key Highlights
- Loaded directly via router configuration
- No module dependency
- Clean and lightweight setup
Products Page – Standalone Component with Routing
Key Highlights:
- Uses *ngFor from CommonModule
- Navigates using RouterLink
- Demonstrates data display in a standalone component
Contact Us Page – Lazy Loaded Standalone Component
Key Highlights:
-
Lazy-loaded at component level
-
No feature module required
-
Improves performance and scalability
Regular Component vs Standalone Component
| Feature | Regular Component | Standalone Component |
| Requires NgModule |
Yes |
No |
| Boilerplate code |
High |
Minimal |
| Lazy loading |
Module-based |
Component-based |
| Dependency handling |
Via modules |
Inside component |
| Reusability |
Limited |
High |
| Recommended for new apps |
No |
Yes |
When NOT to Use Standalone Components
Although standalone components are highly recommended, there are a few scenarios where they might not be ideal:
- Large legacy applications heavily dependent on modules
- Applications running on older Angular versions
- Complex shared module patterns that are expensive to refactor
- Teams not ready to migrate existing module-based architecture
For new projects and modern Angular versions, standalone components should be the default choice.