Standalone Components ๐๏ธ
Standalone components are Angularโs default and recommended approach for building modern applications! Since Angular 19, standalone is the default for all components, directives, and pipes โ you no longer need to set standalone: true explicitly. Think of them as independent LEGO blocks that donโt need a big box (NgModule) to organize them.
๐ฏ What are Standalone Components?
Section titled โ๐ฏ What are Standalone Components?โStandalone components are Angular components that work independently without NgModules. They manage their own dependencies and can be imported directly where needed. Since Angular 19, all components are standalone by default โ no flag needed.
Why Standalone is Now the Standard:
- ๐ฏ Default by Design - All new components are standalone automatically (since Angular 19)
- ๐ซ No NgModules - Skip the module boilerplate entirely
- ๐ฆ Direct Imports - Import exactly what you need, where you need it
- ๐ณ Better Tree Shaking - Smaller bundles with unused code elimination
- โก Simpler Architecture - Less complexity, easier to understand
- ๐ Easy Migration - Can coexist with existing NgModule components
- ๐ Angularโs Direction - The standard for all Angular development
import { Component } from '@angular/core';import { CommonModule } from '@angular/common';import { FormsModule } from '@angular/forms';
@Component({ selector: 'app-user-profile', imports: [CommonModule, FormsModule], // Direct imports template: ` <div class="profile"> <h1>{{ user.name }}</h1> <input [(ngModel)]="user.email" placeholder="Email"> <button (click)="save()">Save</button> </div> `})export class UserProfileComponent { user = { name: 'John Doe', email: 'john@example.com' };
save() { console.log('Saving user:', this.user); }}โ Modern Angular (Standalone - Default)
Section titled โโ Modern Angular (Standalone - Default)โ// Just import the component directly - no modules needed!import { UserProfileComponent } from './user-profile.component';
@Component({ imports: [UserProfileComponent], // Direct import template: `<app-user-profile></app-user-profile>`})export class AppComponent { }๐ฏ Angular CLI Default Behavior
Section titled โ๐ฏ Angular CLI Default BehaviorโNew Angular projects generate standalone components by default โ no flags needed!
# Create a new Angular project (standalone by default)ng new my-app
# Generate a new component (standalone by default since Angular 19)ng generate component user-profile# Creates: user-profile.component.ts โ standalone automaticallyGenerated component structure:
// Generated component โ standalone by default, no flag needed@Component({ selector: 'app-user-profile', imports: [CommonModule], templateUrl: './user-profile.component.html', styleUrl: './user-profile.component.css'})export class UserProfileComponent { }๐ Common Patterns
Section titled โ๐ Common Patternsโ1. Basic Standalone Component
Section titled โ1. Basic Standalone Componentโ@Component({ selector: 'app-counter', template: ` <div> <p>Count: {{ count }}</p> <button (click)="increment()">+</button> <button (click)="decrement()">-</button> </div> `})export class CounterComponent { count = 0;
increment() { this.count++; } decrement() { this.count--; }}2. Standalone with Services
Section titled โ2. Standalone with Servicesโ@Injectable({ providedIn: 'root' })export class UserService { getUsers() { return ['Alice', 'Bob', 'Charlie']; }}
@Component({ selector: 'app-user-list', imports: [CommonModule], template: ` <ul> @for (user of users; track user) { <li>{{ user }}</li> } </ul> `})export class UserListComponent { users = inject(UserService).getUsers();}3. Standalone with Child Components
Section titled โ3. Standalone with Child Componentsโ@Component({ selector: 'app-user-card', template: ` <div class="card"> <h3>{{ user.name }}</h3> <p>{{ user.email }}</p> </div> `, inputs: ['user']})export class UserCardComponent { user!: { name: string; email: string };}
@Component({ selector: 'app-dashboard', imports: [CommonModule, UserCardComponent], // Import child component template: ` <div class="dashboard"> <h2>User Dashboard</h2> @for (user of users; track user.id) { <app-user-card [user]="user"></app-user-card> } </div> `})export class DashboardComponent { users = [ { id: 1, name: 'Alice', email: 'alice@example.com' }, { id: 2, name: 'Bob', email: 'bob@example.com' } ];}4. Standalone Routing
Section titled โ4. Standalone Routingโexport const routes: Routes = [ { path: 'users', loadComponent: () => import('./user-list.component').then(c => c.UserListComponent) }, { path: 'profile', loadComponent: () => import('./user-profile.component').then(c => c.UserProfileComponent) }];
// main.tsbootstrapApplication(AppComponent, { providers: [ provideRouter(routes), // โ
No RouterModule needed provideHttpClient() // โ
No HttpClientModule needed ]});โ Best Practices
Section titled โโ Best Practicesโ1. Import What You Need
Section titled โ1. Import What You Needโ// โ
Good - Import specific modules@Component({ imports: [CommonModule, FormsModule, RouterModule], // ...})
// โ Avoid - Don't create unnecessary modules@NgModule({ imports: [CommonModule, FormsModule], exports: [CommonModule, FormsModule]})export class SharedModule { } // Not needed with standalone!2. Use Providers Array
Section titled โ2. Use Providers Arrayโ// โ
Good - Provide services directly@Component({ providers: [UserService], // Component-level service // ...})
// โ
Better - Use providedIn: 'root' for global services@Injectable({ providedIn: 'root' })export class UserService { }3. Organize Imports
Section titled โ3. Organize Importsโ// โ
Good - Group imports logically@Component({ imports: [ // Angular modules CommonModule, FormsModule, RouterModule,
// Your components UserCardComponent, LoadingSpinnerComponent ], // ...})๐ฏ Quick Checklist
Section titled โ๐ฏ Quick Checklistโ- Components are standalone by default โ no flag needed (Angular 19+)
- Import necessary modules in the
importsarray - Import the component directly where needed
- Use
loadComponentfor lazy loading - Provide services using
providedIn: 'root'or component providers - For legacy NgModule projects, consider migrating with
ng generate @angular/core:standalone
๐ Next Steps
Section titled โ๐ Next Stepsโ- Angular Signals - Modern reactivity with standalone components
- Computed Signals - Derived state in standalone apps
- Control Flow - New template syntax with standalone components
Remember: Standalone components are Angularโs default architecture since Angular 19! All new components are standalone automatically โ no flag needed. If youโre working with legacy NgModule projects, consider migrating with ng generate @angular/core:standalone to enjoy simpler, more modular code! ๐