← Back to Chapters

Angular Modules

? Angular Modules

Angular 15+ Architecture

? Quick Overview

Angular applications traditionally use NgModules to organize components, directives, pipes, and services. From Angular 15+, you can build apps using standalone components, which remove the need for NgModules, simplify project structure, and reduce boilerplate while still allowing gradual migration from existing module-based apps.

? Key Concepts

  • NgModule: A container that groups related components, directives, pipes, and services.
  • Standalone Component: A component that can be used and bootstrapped without being declared in an NgModule.
  • bootstrapApplication: A modern API that bootstraps a standalone-based Angular application.
  • Imports Array: Both NgModules and standalone components use imports to bring in dependencies.
  • Gradual Migration: You can mix NgModules and standalone components in the same app while migrating.

? Syntax & Theory

In a traditional NgModule-based app, the root module (often AppModule) declares all components and bootstraps the root component. In the standalone approach, components set standalone: true and can be directly imported into other standalone components or bootstrapped with bootstrapApplication().

Standalone components still rely on Angular feature modules (like BrowserModule or CommonModule), but these are imported directly into the component rather than via an NgModule's imports.

? Traditional NgModule

This is the classic way of bootstrapping an Angular application using a root AppModule.

? View NgModule Code Example
// app.module.ts - classic Angular root module
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';

@NgModule({
  declarations: [AppComponent, HomeComponent],
  imports: [BrowserModule],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

? Standalone Component Approach

Here, the HomeComponent is marked as standalone and is bootstrapped via bootstrapApplication() instead of being declared in an NgModule.

? View Standalone Code Example
// home.component.ts - standalone component
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-home',
  standalone: true,
  imports: [CommonModule],
  template: '<h2>Welcome Home</h2>'
})
export class HomeComponent { }

// main.ts - bootstrap using bootstrapApplication
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { HomeComponent } from './app/home/home.component';

bootstrapApplication(AppComponent, {
  imports: [HomeComponent]
});

? Explanation & Output

  • In the NgModule example, Angular starts from AppModule, looks at the declarations, and bootstraps AppComponent.
  • In the standalone example, HomeComponent is self-contained and imported directly in the bootstrapApplication() call.
  • The rendered DOM will contain the template from AppComponent, which can use <app-home> and display: <h2>Welcome Home</h2>.
  • Standalone components reduce boilerplate, simplify lazy loading, and make dependency management more straightforward, while still allowing you to keep NgModules where they make sense (like shared libraries).

? When to Use What?

  • Use standalone components for new Angular projects to keep structure minimal.
  • Keep NgModules for existing large apps and shared feature libraries during migration.
  • Hybrid approach: Start creating new features as standalone while old parts still use NgModules, then gradually refactor.

✅ Tips & Best Practices

  • Prefer standalone components for new screens and features to reduce future refactoring.
  • Do not declare standalone components inside an NgModule’s declarations array.
  • Always import required Angular modules (like CommonModule) in the imports array of the standalone component.
  • Use standalone components with Angular routing for a clean, modern app setup.
  • Refactor gradually: convert feature modules to standalone routes one step at a time.

? Try It Yourself

  • Create a simple NgModule-based app with AppModule and HomeComponent, then rewrite it using a standalone HomeComponent.
  • Bootstrap both versions and compare the number of files and configuration code you need.
  • Add routing that navigates to a standalone HomeComponent and a module-based feature component.
  • Experiment with lazy loading using a traditional feature module vs a standalone route component.
  • Identify parts of an existing Angular project that can safely be migrated to standalone components first.