Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Chapter 14: Standalone-First Architecture

Angular’s introduction of standalone components, directives, and pipes (v14) and standalone route APIs (v15+) marked a major shift in how Angular apps can be built. By Angular v17, the recommended best practice for new projects is standalone-first architecture.

In this chapter, we’ll explore how to design, organize, and scale Angular applications in a module-free world (while still interoperating with modules when needed).


14.1 What Does Standalone-First Mean?

Traditionally, every component had to be declared inside an NgModule. With standalone, a component declares itself:

@Component({
  selector: 'app-hello',
  standalone: true,
  template: `<h1>Hello Standalone!</h1>`
})
export class HelloComponent {}

Standalone-first means:

  • No AppModule (bootstrapped with bootstrapApplication).
  • No feature modules — just folders of standalone components and services.
  • Routes and providers defined at the top level.

14.2 Bootstrapping Without AppModule

import { bootstrapApplication } from '@angular/platform-browser';
import { provideRouter } from '@angular/router';
import { provideHttpClient } from '@angular/common/http';

import { AppComponent } from './app/app.component';
import { routes } from './app/app.routes';

bootstrapApplication(AppComponent, {
  providers: [
    provideRouter(routes),
    provideHttpClient()
  ]
});

✅ The app starts from AppComponent.
✅ All providers (router, HTTP, services) are declared in bootstrapApplication.


14.3 Feature Organization Without Modules

Instead of creating UsersModule, you create a users/ folder with:

users/
  users.component.ts
  user-list.component.ts
  user-detail.component.ts
  users.routes.ts
  user.service.ts

Routes file (users.routes.ts):

import { Routes } from '@angular/router';
import { UserListComponent } from './user-list.component';
import { UserDetailComponent } from './user-detail.component';

export const USERS_ROUTES: Routes = [
  { path: '', component: UserListComponent },
  { path: ':id', component: UserDetailComponent }
];

Imported in app.routes.ts:

import { Routes } from '@angular/router';

export const routes: Routes = [
  { path: 'users', loadChildren: () => import('./users/users.routes').then(r => r.USERS_ROUTES) }
];

✅ No feature module required.


14.4 Shared Features Without Modules

For reusable pieces (like buttons, pipes, or directives), create a shared/ folder with standalone exports.

shared/
  components/
    button.component.ts
  pipes/
    truncate.pipe.ts
  directives/
    autofocus.directive.ts

Each is marked standalone: true, so they can be imported directly into any component:

@Component({
  selector: 'app-home',
  standalone: true,
  imports: [ButtonComponent, TruncatePipe],
  template: `
    <app-button>Click</app-button>
    <p>{{ longText | truncate:20 }}</p>
  `
})
export class HomeComponent {}

14.5 Core Services Without a CoreModule

Previously, singletons were placed in CoreModule. With standalone-first, just provide them in root or via bootstrapApplication.

@Injectable({ providedIn: 'root' })
export class AuthService { /* ... */ }

Or explicitly:

bootstrapApplication(AppComponent, {
  providers: [
    AuthService
  ]
});

14.6 Standalone + Signals = Simpler State

In a standalone-first app, signals pair beautifully with services to manage state. Example:

@Injectable({ providedIn: 'root' })
export class CartStore {
  items = signal<string[]>([]);
  add(item: string) { this.items.update(list => [...list, item]); }
}

Directly consumed in standalone components without any NgModule wiring.


14.7 Interoperability with Modules

Standalone-first doesn’t mean modules are gone:

  • You can import an NgModule inside a standalone component (imports: [FormsModule]).
  • You can use standalone components inside old module-based apps.

This ensures backward compatibility and a smooth migration path.


14.8 Benefits of Standalone-First Architecture

  • 🚀 Simpler mental model: no declarations/import confusion.
  • 🧩 Composable: features are just components + routes.
  • 🏗️ Scalable: folder-based organization replaces module overhead.
  • 🔄 Incremental adoption: standalone works alongside NgModules.
  • ✨ Future-proof: aligns with Angular’s roadmap.

14.9 Example Project Structure

src/app/
  app.component.ts
  app.routes.ts
  users/
    user-list.component.ts
    user-detail.component.ts
    users.routes.ts
    user.service.ts
  products/
    product-list.component.ts
    product-detail.component.ts
    products.routes.ts
    product.service.ts
  shared/
    components/
    pipes/
    directives/

✅ Clear, feature-based, no modules needed.


14.10 Summary

  • Standalone-first is Angular’s new recommended architecture.
  • No AppModule — apps start with bootstrapApplication.
  • Features are organized in folders with routes, services, and standalone components.
  • Shared UI elements live in a shared/ folder.
  • Modules are still supported but optional.