Angular Dynamic Components
Create components at runtime withcreateComponent(), or render selectorless standalone components with*ngComponentOutlet.
Dynamic Components Essentials
- createComponent(): Create components at runtime and pass
inputs,outputs, anddirectivesdirectly. - Selectorless components: Standalone components can be used without a selector via
*ngComponentOutlet. - Signals: Drive dynamic state from
signal()and read in templates by calling the signal.
Notes:
- Related: SeeControl Flow for
@if/@for, andSignals for state and effects. - Prefer selectorless +
*ngComponentOutletfor simple outlets; usecreateComponent()for fine-grained control (host element, directives, lifecycle).
createComponent() with inputs & outputs
- Provide
inputs/outputsand an optionalhostElementto attach into the DOM. - Use
EnvironmentInjector(orinject()) so the component can resolve providers.
Example
import { bootstrapApplication } from '@angular/platform-browser';import { Component, EventEmitter, Output, Input, ElementRef, ViewChild, inject, EnvironmentInjector, ComponentRef } from '@angular/core';import { createComponent } from '@angular/core';@Component({ standalone: true, template: ` <div> <h4>{{ title }}</h4> <button (click)="clicked.emit()">Click</button> </div> `})export class Card { @Input() title = 'Card'; @Output() clicked = new EventEmitter<void>();}@Component({ selector: 'app-root', standalone: true, template: ` <h3>Dynamic createComponent()</h3> <div #host></div> <div> <button (click)="mount()">Mount</button> <button (click)="update()">Update input</button> <button (click)="unmount()">Unmount</button> </div> `})export class App { @ViewChild('host', { read: ElementRef }) host!: ElementRef<HTMLElement>; env: EnvironmentInjector = inject(EnvironmentInjector); ref: ComponentRef<Card> | null = null; mount() { if (this.ref) return; this.ref = createComponent(Card, { environmentInjector: this.env, hostElement: this.host.nativeElement }); this.ref.setInput?.('title', 'Hello from Dynamic'); this.ref.instance.clicked.subscribe(() => alert('Card clicked')); } update() { if (!this.ref) return; this.ref.setInput?.('title', 'Updated Title ' + new Date().toLocaleTimeString()); } unmount() { this.ref?.destroy(); this.ref = null; }}bootstrapApplication(App);<app-root></app-root>Example explained
- createComponent(Card, ...): Creates the
Cardcomponent at runtime and returns a component ref. - environmentInjector: Supplies DI so the dynamic component can resolve providers.
- hostElement: Attaches the component's host into the given DOM element (
#host). - inputs/outputs: Sets initial inputs and wires output callbacks (e.g.,
clicked). - setInput / destroy: Update inputs later with
ref.setInput(...)and clean up viaref.destroy().
Notes:
- Cleanup: Always call
destroy()on the component ref when removing it. - Updating inputs: Use
setInput(name, value)on the component ref to push new input values.
Selectorless via *ngComponentOutlet
- Render a standalone component without a selector using
*ngComponentOutlet. - Pass
inputsandoutputsinline in the outlet micro-syntax.
Example
import { bootstrapApplication } from '@angular/platform-browser';import { Component, EventEmitter, Output, Input, signal } from '@angular/core';import { NgComponentOutlet } from '@angular/common';@Component({ standalone: true, template: `<button (click)="clicked.emit()">{{ label }}</button>`})export class ActionButton { @Input() label = 'Do it'; @Output() clicked = new EventEmitter<void>();}@Component({ selector: 'app-root', standalone: true, imports: [NgComponentOutlet], template: ` <h3>Selectorless via *ngComponentOutlet</h3> <p>Clicks: {{ clicks() }}</p> <ng-container *ngComponentOutlet="ActionButton; inputs: { label: 'Launch' }; outputs: { clicked: onClick }"></ng-container> `})export class App { ActionButton = ActionButton; clicks = signal(0); onClick = () => this.clicks.update(n => n + 1);}bootstrapApplication(App);<app-root></app-root>Example explained
- *ngComponentOutlet="ActionButton": Renders the standalone component class referenced by
ActionButton. - inputs / outputs: Pass values and event handlers directly in the outlet micro-syntax.
- Signals for state: The
clickssignal holds state and updates the UI whenonClickincrements it.
Notes:
- Inputs/Outputs: The outlet micro-syntax supports
inputsandoutputsbags for easy wiring. - Composition: Use outlets inside
@if/@forfor conditional or repeated dynamic UIs.

