Skip to main content
Standalone Components

Standalone Components Overview

Estimated Time: 2 hours | Difficulty: Intermediate | Prerequisites: Components, Modules
Standalone components are Angular’s modern approach to building applications without NgModules. Introduced in Angular 14 and becoming the default in Angular 17+, they simplify the mental model and improve tree-shaking. If you have ever been confused about why you had to declare a component in one module, import that module into another module, and then export the component from the first module just to use it — standalone components are the answer. With the traditional NgModule system, the dependency graph lived in module files that were often hundreds of lines long and hard to reason about. Standalone components make each component self-describing: open the file, and the imports array tells you exactly what that component depends on. No more hunting through module files to figure out why something is or is not available.

Creating Standalone Components

Basic Standalone Component

Standalone Component with Providers


Standalone Directives & Pipes

Standalone Directive

Standalone Pipe


Bootstrapping Standalone Applications

Modern Application Bootstrap

Provider Functions Pattern

The provide*() function pattern is how Angular’s own APIs are structured (provideRouter, provideHttpClient, etc.) and it is the recommended way to package your own application-wide configuration. Instead of scattering provider arrays across your codebase, you create a single function that encapsulates all the pieces a feature needs — services, tokens, initializers — and returns them as a unit.

Lazy Loading Standalone Components

Lazy loading was possible with NgModules, but it required wrapping components in a module just to make them lazy-loadable. With standalone components, any component can be lazy loaded directly via loadComponent. This is one of the biggest practical wins of the standalone architecture — you no longer need to create a module for the sole purpose of enabling lazy loading.
loadComponent vs loadChildren: Use loadComponent when you want to lazy-load a single component (a page, a dialog). Use loadChildren when you want to lazy-load an entire route tree with nested child routes. Both use the same dynamic import() mechanism under the hood.

Route-Level Lazy Loading

Dynamic Component Loading


Migrating from NgModules

Migration Strategy

Migration pitfall: The most common issue during NgModule-to-standalone migration is missing imports. In an NgModule world, a component might use NgIf without explicitly importing it because the parent module imported CommonModule. When you make that component standalone, you must add CommonModule (or the individual NgIf directive) to its own imports array. The automated migration schematic handles most cases, but always run your tests after each phase to catch what it misses.

Automated Migration

Manual Migration Example

Should you use convenience arrays or individual imports? For small teams and small shared libraries, convenience arrays are fine — the tree-shaking impact is negligible. For published libraries or monorepos with many consumers, prefer individual imports so that unused components are eliminated from the bundle. The rule of thumb: if every consumer uses most of the shared components, arrays are convenient. If consumers cherry-pick one or two items, individual imports are better.

Best Practices

Organize by Feature

Group related standalone components, services, and routes by feature

Use Index Exports

Create barrel files (index.ts) for convenient imports

Provider Functions

Create reusable provider functions for complex configurations

Explicit Dependencies

Import only what each component needs - improves tree-shaking

Folder Structure for Standalone


Practice Exercise

1

Create Standalone Library

Build a reusable UI component library with standalone components
2

Migrate Existing App

Take a NgModule-based app and migrate it to fully standalone
3

Implement Lazy Loading

Set up advanced lazy loading patterns with preloading strategies

Next: NgRx State Management

Master reactive state management with NgRx Store, Effects, and Selectors