Angular Standalone Components richtig einsetzen und migrieren

6. Juli 2026

Angular-Logo über "CoreModule" und "Standalone APIs". Ein Pfeil verbindet die beiden Konzepte, was die Flexibilität eines angular standalone component zeigt.

Inhaltsverzeichnis

Eine Angular-Anwendung wird schnell unübersichtlich, wenn jede neue Funktion erst über mehrere NgModule verdrahtet werden muss. Standalone Components lösen genau dieses Problem, indem sie ihre Abhängigkeiten direkt am Baustein deklarieren. Ich zeige, wie das Modell funktioniert, welche Vorteile es im Alltag bringt, wann NgModules weiterhin eine Rolle spielen und wie sich bestehende Projekte sicher umstellen lassen.

Standalone Components machen Angular modularer und direkter

  • Direkte Abhängigkeiten werden im Feld imports der Component festgelegt.
  • NgModules sind für neue Angular-Projekte meist nicht mehr der notwendige Einstiegspunkt.
  • bootstrapApplication startet eine Anwendung direkt über ihre Root-Component.
  • Lazy Loading wird mit loadComponent besonders übersichtlich.
  • Migrationen sollten schrittweise erfolgen und nach jedem Schritt getestet werden.

Architekturdiagramm zeigt einen Main Component, der über den Main Router mit Guard zu Feature Components und dem Auth Component führt. Jede Feature Component hat Service Facades und Presentational Components. Shared-Standalone-Elemente wie Pipes und Di...

Was eine standalone Component in Angular anders macht

Die englische Bezeichnung angular standalone component steht für eine Angular-Component, die ohne Eintrag in einem NgModule verwendet werden kann. Sie bringt ihre benötigten Components, Direktiven und Pipes direkt über imports mit. Dadurch ist auf einen Blick erkennbar, wovon der Baustein tatsächlich abhängt.

In älteren Angular-Projekten lagen diese Informationen häufig in einem Modul. Eine Component wurde dort unter declarations registriert, ein gemeinsames Modul exportierte sie und ein anderes importierte dieses Modul wieder. Das funktionierte, erzeugte aber schnell indirekte Abhängigkeiten, die bei größeren Teams schwer nachzuvollziehen waren.

Eine Standalone Component ist deshalb nicht einfach eine Component mit einem anderen Schalter. Sie verändert die Struktur der Anwendung. Ich empfinde besonders die klare lokale Zuständigkeit als Gewinn: Wer eine Datei öffnet, sieht meist sofort, welche UI-Bausteine und Template-Funktionen sie verwendet.

Was weiterhin gleich bleibt

Die Component besteht nach wie vor aus einer TypeScript-Klasse, einem Template und optionalen Styles. Inputs, Outputs, Dependency Injection, Routing und Lifecycle Hooks funktionieren weiterhin nach denselben Grundprinzipien. Standalone bedeutet nicht eigenständig im fachlichen Sinn, sondern unabhängig von einem NgModule.

Auch bestehende NgModules verschwinden nicht automatisch. Eine Standalone Component kann weiterhin ein vorhandenes NgModule importieren, wenn eine Bibliothek noch keine eigenständigen Direktiven oder Provider anbietet. Das macht die Umstellung deutlich weniger riskant, als viele zunächst vermuten.

So baust du eine Standalone Component auf

Eine einfache Component lässt sich mit der Angular CLI erzeugen. Bei aktuellen CLI-Projekten ist die Standalone-Variante der übliche Standard, ich schreibe die Einstellung im Beispiel trotzdem ausdrücklich hin. So wird die Architektur auch für Personen verständlich, die aus einem älteren Projekt kommen.

ng generate component product-card

Das folgende Beispiel zeigt eine kleine Produktkarte mit einer Pipe und einer Benutzeraktion.

import { CurrencyPipe } from '@angular/common';
import { Component } from '@angular/core';

@Component({
  selector: 'app-product-card',
  standalone: true,
  imports: [CurrencyPipe],
  template: `
    

{{ name }}

{{ price | currency:'EUR' }}

` }) export class ProductCardComponent { name = 'Noise-Cancelling-Kopfhörer'; price = 129.99; addToCart(): void { console.log('Produkt hinzugefügt'); } }

Der entscheidende Punkt ist imports: [CurrencyPipe]. Die Pipe wird nicht in einem gemeinsamen Modul bereitgestellt, sondern dort importiert, wo sie im Template gebraucht wird. Fehlt der Import, meldet Angular normalerweise schon beim Kompilieren, dass die verwendete Template-Funktion nicht bekannt ist.

Andere Components direkt einbinden

Eine Standalone Component wird in einer anderen Standalone Component ebenfalls direkt importiert. Zusätzlich muss sie im imports-Array der aufrufenden Component stehen.

import { Component } from '@angular/core';
import { ProductCardComponent } from './product-card.component';

@Component({
  selector: 'app-shop',
  standalone: true,
  imports: [ProductCardComponent],
  template: `
    

Unser Shop

` }) export class ShopComponent {}

Dieser Aufbau wirkt anfangs etwas ausführlicher, ist aber langfristig sauberer. Die Abhängigkeit ist lokal sichtbar und nicht über eine Kette aus SharedModule, FeatureModule und RootModule verteilt.

Direktiven und Pipes gezielt importieren

Für einzelne Template-Funktionen importiere ich möglichst nur das, was wirklich verwendet wird. Bei klassischer Syntax wären das etwa NgIf, NgFor oder AsyncPipe. Moderne Angular-Projekte können außerdem die eingebaute Control-Flow-Syntax mit @if und @for nutzen, wodurch einige Importe über CommonModule entfallen.

Das ist kein Grund, jedes Template zwanghaft umzuschreiben. Entscheidend ist, dass die Component verständlich bleibt und der Build keine unnötigen Abhängigkeiten mitschleppt. Kleine, präzise Imports sind in meinen Augen hilfreicher als eine scheinbar elegante, aber schwer erkennbare Sammellösung.

Bootstrap, Routing und Services ohne NgModule organisieren

Standalone betrifft nicht nur einzelne UI-Bausteine. Eine Anwendung kann auch direkt über ihre Root-Component gestartet werden. Dafür wird bootstrapApplication verwendet.

import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';

bootstrapApplication(AppComponent)
  .catch(error => console.error(error));

Die Root-Component muss standalone sein. Globale Provider wie HTTP, Router, Authentifizierung oder Konfiguration gehören in die Bootstrap-Konfiguration und nicht in eine künstliche Modulstruktur.

import { bootstrapApplication } from '@angular/platform-browser';
import { provideHttpClient } from '@angular/common/http';
import { provideRouter } from '@angular/router';
import { AppComponent } from './app/app.component';
import { routes } from './app/app.routes';

bootstrapApplication(AppComponent, {
  providers: [
    provideHttpClient(),
    provideRouter(routes)
  ]
}).catch(error => console.error(error));

Hier zeigt sich ein wichtiger Unterschied: Components importieren UI-Abhängigkeiten, während die Anwendung globale Services über Provider konfiguriert. Diese Trennung verhindert, dass beispielsweise ein API-Service versehentlich nur innerhalb eines einzelnen Templates verfügbar ist.

Lazy Loading wird besonders übersichtlich

Für größere Anwendungen ist die Kombination aus Standalone Components und Lazy Loading sehr praktisch. Eine Route kann eine Component erst laden, wenn der entsprechende Bereich tatsächlich aufgerufen wird.

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

export const routes: Routes = [
  {
    path: 'einstellungen',
    loadComponent: () =>
      import('./settings/settings.component')
        .then(module => module.SettingsComponent)
  }
];

Das reduziert nicht automatisch jede Ladezeit auf einen bestimmten Wert. Der tatsächliche Effekt hängt von Bundle-Größe, Bildern, Drittanbieterpaketen und Server-Konfiguration ab. In der Praxis entsteht aber eine klarere Aufteilung der JavaScript-Bundles, vor allem bei Anwendungen mit vielen selten besuchten Bereichen.

NgModule-Bibliotheken schrittweise weiterverwenden

Eine ältere Bibliothek muss nicht sofort ersetzt werden. Für ihre Provider kann importProvidersFrom verwendet werden. Das ist besonders nützlich, wenn ein Paket noch eine Konfiguration über ein NgModule erwartet.

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

Ich würde diese Möglichkeit als Brücke für eine Übergangsphase betrachten, nicht als Zielarchitektur. Sie hilft, Abhängigkeiten zu modernisieren, ohne eine komplette Anwendung an einem einzigen Wochenende umzubauen.

Standalone oder NgModule welches Modell passt besser

Für neue Angular-Anwendungen empfiehlt die Angular-Dokumentation den Standalone-Ansatz. Trotzdem ist ein NgModule-basiertes Projekt nicht automatisch veraltet oder schlecht strukturiert. Die bessere Entscheidung hängt von Codebasis, Team, Bibliotheken und geplanter Lebensdauer ab.

Kriterium Standalone Components NgModules
Neue Projekte Meist die klarere Wahl Nur bei konkretem Kompatibilitätsgrund
Abhängigkeiten Direkt an der Component sichtbar Oft über Module gebündelt
Lazy Loading Mit loadComponent sehr direkt Häufig über Lazy-loaded NgModules
Migration Für neue Bereiche sofort nutzbar Kann zunächst weiterlaufen
Bibliothekskompatibilität Gut, aber abhängig von der jeweiligen Bibliothek Bei älteren Paketen oft unkomplizierter

Für ein neues Produkt würde ich heute mit Standalone starten. Bei einem großen Bestandssystem mit stabilen NgModules sehe ich dagegen keinen Wert darin, jede Datei nur aus Prinzip umzubauen. Technische Migrationen sollten ein Problem lösen, etwa schwer verständliche Abhängigkeiten, langsame Builds oder eine neue Routing-Struktur.

Ein häufiger Denkfehler ist außerdem die Erwartung, Standalone Components würden automatisch eine deutlich kleinere Anwendung erzeugen. Sie können Abhängigkeiten präziser machen und Lazy Loading erleichtern, aber die Architektur ersetzt keine Bundle-Analyse. Unnötige UI-Bibliotheken, große Datenpakete und falsch konfigurierte Polyfills bleiben auch in einer Standalone-Anwendung problematisch.

Ein bestehendes Projekt sicher migrieren

Angular stellt für die Umstellung ein offizielles Migrations-Schematic bereit. Der sichere Weg besteht aus mehreren Durchläufen. Vor dem Start sollte das Projekt ohne Compilerfehler bauen und der aktuelle Stand in einem sauberen Git-Branch gesichert sein.

  1. Components, Direktiven und Pipes konvertieren und ihre Template-Abhängigkeiten in imports verschieben.
  2. Überflüssige NgModules entfernen, nachdem die erste Version erfolgreich kompiliert.
  3. Das Bootstrap-Verfahren umstellen und bootstrapModule durch bootstrapApplication ersetzen.
  4. Tests, Linting und Formatierung ausführen und verbleibende manuelle Stellen prüfen.
ng generate @angular/core:standalone

Das Werkzeug automatisiert viel, aber nicht alles. Es kann Schwierigkeiten mit dynamisch erzeugten Metadaten, eigenen Wrappern um Angular-APIs oder Dateien geben, die nicht in der verwendeten TypeScript-Konfiguration enthalten sind. Deshalb würde ich nach jedem Migrationsschritt bauen und testen, statt alle Änderungen am Ende gesammelt zu kontrollieren.

Lesen Sie auch: Publisher im Web - Aufgaben, Rollen und Publishing-Workflow

Tests müssen ebenfalls angepasst werden

Bei einer Standalone Component gehört die getestete Component in vielen TestBed-Konfigurationen zu imports und nicht zu declarations.

await TestBed.configureTestingModule({
  imports: [ProductCardComponent]
}).compileComponents();

Gerade bei großen Test-Suites tauchen solche Fehler oft erst spät auf. Ich plane deshalb die Anpassung der Tests nicht als Nacharbeit ein, sondern als festen Teil jedes Migrationsschritts. Das spart Zeit und zeigt schneller, ob die neue Importstruktur tatsächlich vollständig ist.

Typische Fehler bei der täglichen Arbeit

Der häufigste Fehler ist ein fehlender Import. Eine Component verwendet beispielsweise eine Pipe oder ein Kind-Element im Template, führt es aber nicht in imports auf. Der Compiler hilft hier zwar, doch bei komplexen Templates kann die Fehlermeldung zunächst verwirrend wirken.

Ein zweites Problem entsteht durch zu große Sammel-Components. Standalone macht es leicht, viele Abhängigkeiten direkt einzutragen. Das bedeutet aber nicht, dass eine einzelne Page-Component plötzlich für Formulare, Navigation, Datenzugriff und Modalfenster zuständig sein sollte. Lokale Imports verbessern die Struktur nur dann, wenn die fachlichen Grenzen ebenfalls sinnvoll gesetzt sind.

Auch Provider werden gelegentlich am falschen Ort registriert. Ein globaler Authentifizierungsdienst gehört meist in die Anwendungskonfiguration, ein zustandsbezogener Dienst für einen bestimmten Bereich kann dagegen an einer Route oder Component sinnvoll sein. Der richtige Ort hängt davon ab, wie lange die Instanz leben und wer sie teilen soll.

Schließlich sollte niemand NgModules aus einer funktionierenden Legacy-Bibliothek gewaltsam entfernen. Eine schrittweise Mischung ist erlaubt und oft vernünftig. Erst wenn Ersatzpakete, Tests und Build-Prozess stabil sind, lohnt sich die vollständige Bereinigung.

Die wichtigste Architekturentscheidung liegt nicht im Decorator

Eine Standalone Component ist vor allem ein Werkzeug für klare Abhängigkeiten, kleinere Zuständigkeiten und flexibleres Routing. Der eigentliche Nutzen entsteht nicht durch das einzelne standalone: true, sondern durch die konsequente Entscheidung, Verantwortlichkeiten sichtbar und lokal zu halten.

Für neue Angular-Projekte ist der Einstieg unkompliziert: Component erzeugen, benötigte UI-Bausteine importieren, globale Provider beim Bootstrap konfigurieren und große Bereiche über Routen lazy laden. Bestehende Anwendungen dürfen langsamer wachsen. In meinen Projekten ist eine kontrollierte Teilmigration meist wertvoller als ein riskanter Komplettumbau.

Wer diese Grenzen beachtet, bekommt keine magische Performance-Lösung, aber eine Angular-Codebasis, die sich leichter lesen, testen und weiterentwickeln lässt. Genau darin liegt für mich der nachhaltige Vorteil des Standalone-Modells.

Häufig gestellte Fragen

Standalone Components benötigen keinen Eintrag in einem NgModule. Components, Direktiven und Pipes werden direkt im imports-Array der Component angegeben, sodass ihre Abhängigkeiten lokal sichtbar bleiben.

Eine standalone Root-Component wird mit bootstrapApplication gestartet. Globale Provider wie HTTP und Router werden dabei über provideHttpClient() und provideRouter(routes) in der Bootstrap-Konfiguration registriert.

Bestehende NgModules können weiterverwendet werden, insbesondere wenn ältere Bibliotheken noch keine standalone Direktiven oder Provider anbieten. Für deren Provider dient importProvidersFrom als Übergangslösung.

Die Migration sollte schrittweise mit ng generate @angular/core:standalone erfolgen. Nach jeder Phase sollten Build, Tests, Linting und Formatierung ausgeführt werden; bei TestBed-Konfigurationen gehört die standalone Component meist in imports statt in declarations.

Routen können eine Component mit loadComponent erst beim Aufruf laden. Dadurch wird die Aufteilung der JavaScript-Bundles übersichtlicher, wobei der tatsächliche Ladeeffekt von Bundle-Größe, Bildern, Drittanbieterpaketen und Server-Konfiguration abhängt.

Artikel bewerten

Bewertung: 0.00 Stimmenanzahl: 0

Tags:

lazy loading routing standalone components ngmodules angular cli

Beitrag teilen

Edwin Appel

Edwin Appel

Mein Name ist Edwin Appel und seit 11 Jahren beschäftige ich mich intensiv mit den sich ständig weiterentwickelnden Welten der Webentwicklung, der digitalen Strategie und der künstlichen Intelligenz. Diese Themen sind für mich mehr als nur berufliche Felder; sie sind faszinierende Bereiche, in denen ich gerne komplexe Zusammenhänge aufschlüssele und verständlich mache. Auf metawebart.de teile ich meine Erkenntnisse und Erfahrungen, um Ihnen dabei zu helfen, die digitalen Herausforderungen unserer Zeit besser zu verstehen und zu meistern. Mein Ziel ist es, Ihnen stets fundierte, nachvollziehbare und aktuelle Informationen zu liefern, die Ihnen bei Ihrer eigenen digitalen Reise nützlich sind.

Kommentar schreiben