Angular Component Generator
Creates a single, modern Angular component file that follows current Angular (v20+) conventions.
Conventions to Follow
- Standalone - do NOT set
standalone: true(it's the default in v20+) - Change detection - always set
changeDetection: ChangeDetectionStrategy.OnPush - Inputs / outputs - use
input()andoutput()functions, not decorators - State - use
signal()for local state,computed()for derived state - Templates - prefer inline
template; use@if/@for/@switch(not*ngIf/*ngFor/*ngSwitch) - Bindings - use
class.xandstyle.xbindings (notngClass/ngStyle) - Host - put host bindings/listeners in the
hostobject (not@HostBinding/@HostListener) - Injection - use the
inject()function, not constructor injection - Selector - kebab-case with an
app-prefix (e.g.app-user-card) - File name -
<name>.component.tsinsrc/app/<name>/ - Class name - PascalCase ending in
Component(e.g.UserCardComponent)
Workflows
- Confirm the component name with the user (if not provided) and derive:
- Folder:
src/app/<kebab-name>/ - File:
<kebab-name>.component.ts - Selector:
app-<kebab-name> - Class:
<PascalName>Component
- Folder:
- Generate the file using the template below.
- Only create a separate
.html/.cssfile if the template or styles are large enough to justify it; otherwise keep them inline.
Template
import { ChangeDetectionStrategy, Component, input, output, signal, computed } from '@angular/core';
@Component({
selector: 'app-<kebab-name>',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<section class="<kebab-name>">
<h2>{{ title() }}</h2>
@if (hasItems()) {
<ul>
@for (item of items(); track item) {
<li>{{ item }}</li>
}
</ul>
} @else {
<p>No items yet.</p>
}
<button type="button" (click)="select.emit(title())">Select</button>
</section>
`,
styles: `
.<kebab-name> { display: block; }
`,
})
export class <PascalName>Component {
readonly title = input.required<string>();
readonly items = input<readonly string[]>([]);
readonly select = output<string>();
protected readonly hasItems = computed(() => this.items().length > 0);
protected readonly isBusy = signal(false);
}
Example
Request: "Create a user-card component with a name input and a selected output."
Output file: src/app/user-card/user-card.component.ts
import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';
@Component({
selector: 'app-user-card',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<article class="user-card">
<h3>{{ name() }}</h3>
<button type="button" (click)="selected.emit(name())">Select</button>
</article>
`,
styles: `
.user-card { display: block; padding: 0.5rem; }
`,
})
export class UserCardComponent {
readonly name = input.required<string>();
readonly selected = output<string>();
}
Don'ts
- Don't add
standalone: true - Don't use
NgModule - Don't use
@Input()/@Output()decorators - Don't use
*ngIf/*ngFor/*ngSwitch - Don't use
ngClass/ngStyle - Don't inject via the constructor
- Don't import
CommonModulejust to use control flow (native blocks don't need it)