Loading...
Loading...
Modern Angular (v20+) expert with deep knowledge of Signals, Standalone Components, Zoneless applications, SSR/Hydration, and reactive patterns. Use PROACTIVELY for Angular development, component arch
npx skill4agent add ranbot-ai/awesome-skills angularangular-migrationtypescript-expert| Version | Release | Key Features |
|---|---|---|
| Angular 20 | Q2 2025 | Signals stable, Zoneless stable, Incremental hydration |
| Angular 21 | Q4 2025 | Signals-first default, Enhanced SSR |
| Angular 22 | Q2 2026 | Signal Forms, Selectorless components |
import { signal, computed, effect } from "@angular/core";
// Writable signal
const count = signal(0);
// Read value
console.log(count()); // 0
// Update value
count.set(5); // Direct set
count.update((v) => v + 1); // Functional update
// Computed (derived) signal
const doubled = computed(() => count() * 2);
// Effect (side effects)
effect(() => {
console.log(`Count changed to: ${count()}`);
});import { Component, input, output, model } from "@angular/core";
@Component({
selector: "app-user-card",
standalone: true,
template: `
<div class="card">
<h3>{{ name() }}</h3>
<span>{{ role() }}</span>
<button (click)="select.emit(id())">Select</button>
</div>
`,
})
export class UserCardComponent {
// Signal inputs (read-only)
id = input.required<string>();
name = input.required<string>();
role = input<string>("User"); // With default
// Output
select = output<string>();
// Two-way binding (model)
isSelected = model(false);
}
// Usage:
// <app-user-card [id]="'123'" [name]="'John'" [(isSelected)]="selected" />import {
Component,
viewChild,
viewChildren,
contentChild,
} from "@angular/core";
@Component({
selector: "app-container",
standalone: true,
template: `
<input #searchInput />
<app-item *ngFor="let item of items()" />
`,
})
export class ContainerComponent {
// Signal-based queries
searchInput = viewChild<ElementRef>("searchInput");
items = viewChildren(ItemComponent);
projectedContent = contentChild(HeaderDirective);
focusSearch() {
this.searchInput()?.nativeElement.focus();
}
}| Use Case | Signals | RxJS |
|---|---|---|
| Local component state | ✅ Preferred | Overkill |
| Derived/computed values | ✅ | |
| Side effects | ✅ | |
| HTTP requests | ❌ | ✅ HttpClient returns Observable |
| Event streams | ❌ | ✅ |
| Complex async flows | ❌ | ✅ |
import { Component } from "@angular/core";
import { CommonModule } from "@angular/common";
import { RouterLink } from "@angular/router";
@Component({
selector: "app-header",
standalone: true,
imports: [CommonModule, RouterLink], // Direct imports
template: `
<header>
<a routerLink="/">Home</a>
<a routerLink="/about">About</a>
</header>
`,
})
export class HeaderComponent {}// main.ts
import { bootstrapApplication } from "@angular/platform-browser";
import { provideRouter } from "@angular/router";
import { provideHttpClient } from "@angular/common/http";
import { AppComponent