Standalone Components: The Right Way to Start a New Angular App

Standalone components killed NgModules. Here’s how the modern Angular setup actually works — bootstrap, routing, lazy loading — and how to migrate an older app.

If you learned Angular before 2023, you learned NgModules. Then you learned how to wire feature modules, shared modules, core modules, and a single root module that imported them all in the right order. Then you spent your career fighting the import graph.

Standalone components killed all of that. If you're starting a new Angular app today, this is the only setup that should be on the table.

What changed

A standalone component declares its own imports. No module. No declarations array. No exports. Just a component class that says what it needs.

``typescript @Component({ selector: 'app-blog-list', imports: [RouterLink, DatePipe], templateUrl: './blog-list.component.html' }) export class BlogListComponent { } ``

That's the whole declaration. The imports array lists every component, directive, and pipe this component uses. If you forget one, the compiler tells you which line broke.

Why this is better

  • Less boilerplate. No module file, no @NgModule decorator, no shared module dance. The component owns its own dependencies.
  • Lazy loading is straightforward. Point a route at a component file and Angular code-splits it. No loadChildren returning a module factory.
  • Tree shaking actually works. If a component isn't imported, it isn't in the bundle. With modules, anything in declarations came along whether you used it or not.
  • Easier to read. You open a component and see exactly what it depends on. You don't have to trace which module declared what.

Bootstrap a standalone app

The main.ts for a standalone app is a single function call:

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

The provideX functions replace what used to live in imports: [HttpClientModule, RouterModule.forRoot(routes), ...]. Same idea, less ceremony.

Routing without module files

Each route can point directly at a standalone component, including lazy-loaded ones:

``typescript export const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'blog', loadComponent: () => import('./pages/blog/blog-list.component') .then(m => m.BlogListComponent) } ]; ``

The loadComponent form is what gets code-split into its own chunk. The Angular CLI handles the chunking automatically — no extra config.

What about shared things?

For shared UI components, just import them where you need them. There's no "shared module" to manage. If you find yourself listing the same five imports in every component, that's a smell — but a manageable one. A small SHARED_UI constant works fine:

```typescript export const SHARED_UI = [ButtonComponent, IconComponent, CardComponent];

@Component({ imports: [...SHARED_UI, RouterLink] }) ```

For services, they're injected via DI as always. Most services should be providedIn: 'root' — tree-shakable, app-wide singletons with no extra wiring.

Migrating from modules

If you have an existing module-based Angular app, you don't have to rewrite it. The Angular CLI has a migration:

``bash ng generate @angular/core:standalone ``

Run it three times — once for each phase (components, routes, bootstrap). It isn't perfect, but it gets you 90% of the way there. The remaining 10% is hand-fixing the edge cases.

What I do on new projects

Every new Angular component I generate is standalone. Every route is loadComponent. The only module-like file is the app.config.ts with the root providers. The whole app feels lighter, both in code and in the bundle.

Standalone components plus Signals are most of what makes modern Angular feel modern. They're also why the framework is lighter on the bundle than its reputation suggests — covered in Angular Performance.

If you're stuck on a legacy Angular app and trying to figure out whether to migrate or rewrite, send me a message. That conversation often saves the rewrite.

Want help shipping this on your own site?

Free 30-minute consultation. No pressure either way.

Start a project