Angular  

Understanding Standalone Components in Angular (with a Real-Time Store Application)

Angular has evolved significantly over the years, and one of the most impactful improvements is the introduction of Standalone Components. This feature simplifies application architecture by reducing boilerplate and making components more self-contained and reusable.

In this article, I’ll explain what standalone components are, how they differ from regular (module-based) components, and when not to use them, using a real-time store application demo that I built locally.

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

  1. Landing Page – Standalone Component Entry Point

1_Landing_Page

Key Highlights:

  • Loaded directly via router configuration

  • No module dependency

  • Clean and lightweight setup

  1. Products Page – Standalone Component with Routing

    2_Products_Page

Key Highlights:

  • Uses *ngFor from CommonModule

  • Navigates using RouterLink

  • Demonstrates data display in a standalone component

  1. Contact Us Page – Lazy Loaded Standalone Component

    3_ContactUs_Page

Key Highlights:

  • Lazy-loaded at component level

  • No feature module required

  • Improves performance and scalability

Regular Component vs Standalone Component

FeatureRegular ComponentStandalone Component
Requires NgModuleYesNo
Boilerplate codeHighMinimal
Lazy loadingModule-basedComponent-based
Dependency handlingVia modulesInside component
ReusabilityLimitedHigh
Recommended for new appsNoYes

When NOT to Use Standalone Components

Although standalone components are highly recommended, there are a few scenarios where they might not be ideal:

  1. Large legacy applications heavily dependent on modules

  2. Applications running on older Angular versions

  3. Complex shared module patterns that are expensive to refactor

  4. Teams not ready to migrate existing module-based architecture

For new projects and modern Angular versions, standalone components should be the default choice.

Conclusion

Standalone components simplify Angular development by:

  • Removing unnecessary modules

  • Improving readability and maintainability

  • Making components self-contained and reusable

  • Enabling easier lazy loading and routing

In this store application demo, standalone components helped create a clean, modern, and scalable architecture without sacrificing functionality.

Source Code

You can find the complete working demo here:

GitHub Repository: Standalone_Component_POC