Standalone Components
If you have read older Angular tutorials, you have seen NgModule — a class decorated with @NgModule that declares which components, directives, and pipes are available together. Every component had to be declared in a module. Modules declared which other modules they imported. The whole system was powerful but verbose.
Angular 14 introduced standalone components, and Angular 17 made them the default. This course uses standalone components exclusively. There are no NgModules anywhere in CinemaVault.
What standalone means
Section titled “What standalone means”A standalone component declares its own dependencies directly in the @Component decorator using the imports array. Instead of relying on a module to make other components and directives available, the component lists exactly what it needs:
import { Component, Input } from '@angular/core';import { CommonModule } from '@angular/common';import { RouterLink } from '@angular/router';import { Movie } from '../../models/movie.model';
@Component({ selector: 'app-movie-card', standalone: true, // ← this is the key option imports: [CommonModule, RouterLink], // ← declare dependencies here templateUrl: './movie-card.html', styleUrl: './movie-card.css'})export class MovieCard { @Input({ required: true }) movie!: Movie;}The imports array lists anything the template uses that is not a standard HTML element: other components, Angular directives like NgIf/NgFor (or the newer @if/@for control flow), pipes, and router directives.
Why standalone is better
Section titled “Why standalone is better”Clarity: Each component explicitly declares what it depends on. Reading the imports array tells you exactly what the template can use.
Simplicity: There are no NgModule files to maintain. No declarations arrays. No forRoot() / forChild() patterns. Components are self-contained.
Lazy loading: Standalone components are easier to lazy-load at the route level because they do not need to be bundled with a module.
Tree-shaking: Bundlers can more easily remove unused code when dependencies are explicit at the component level.
In Angular 17+, standalone is the default
Section titled “In Angular 17+, standalone is the default”When you run ng generate component, the generated component has standalone: true automatically. You do not need to add it. The CLI also no longer creates NgModule files by default.
If you work on an older codebase, you may still encounter NgModules. The concepts are the same — components, templates, inputs, outputs — but the wiring is different.
Bootstrapping standalone apps
Section titled “Bootstrapping standalone apps”bootstrapApplication (in main.ts) is the standalone equivalent of bootstrapping via an AppModule. It accepts the root component and a configuration object:
import { bootstrapApplication } from '@angular/platform-browser';import { appConfig } from './app/app.config';import { App } from './app/app';
bootstrapApplication(App, appConfig);Providers that used to go in AppModule.imports now go in appConfig.providers:
import { ApplicationConfig } from '@angular/core';import { provideRouter } from '@angular/router';import { provideHttpClient } from '@angular/common/http';import { routes } from './app.routes';
export const appConfig: ApplicationConfig = { providers: [ provideRouter(routes), provideHttpClient() ]};Exercise
Section titled “Exercise”- Run
ng generate component components/movie-badgein your practice project. - Confirm the generated file has
standalone: truein the@Componentdecorator. - In
MovieBadge, add an@Input() label = 'New'property and display it in the template. - Use
MovieBadgeinsideMovieCardby adding it toMovieCard’simportsarray and using<app-movie-badge />in the template. - Confirm the app builds without errors.
- Angular 17+ uses standalone components by default — no NgModules needed.
standalone: truein@Componentdeclares the component as self-contained.- The
importsarray in@Componentlists other components, directives, and pipes the template uses. bootstrapApplicationinmain.tsstarts a standalone Angular app.- Providers like the router and
HttpClientgo inappConfig.providersinapp.config.ts.