Loading...
Loading...
Curated Angular best practices for building performant, maintainable applications. Library-specific rules available as optional skills.
npx skill4agent add alfredoperez/angular-best-practices angular-best-practices| Category | Rules | Impact |
|---|---|---|
| Bundle Optimization | 5 | CRITICAL |
| Signals & Reactivity | 5 | HIGH |
| Change Detection | 5 | HIGH |
| Component Patterns | 4 | HIGH |
| RxJS Patterns | 5 | HIGH |
| Testing | 6 | HIGH |
| TypeScript | 14 | MEDIUM |
| Library | Install Command |
|---|---|
| NgRx | |
| SignalStore | |
| TanStack Query | |
| Pattern | Use | Avoid |
|---|---|---|
| Signal inputs | | |
| Signal outputs | | |
| Dependency injection | | Constructor injection |
| Control flow | | |
| Class binding | | |
| Change detection | | Default |
| Derived state | | Getters |
@Component({
selector: 'app-user-card',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
@if (user(); as u) {
<h2>{{ u.name }}</h2>
<button (click)="selected.emit(u)">Select</button>
}
`,
})
export class UserCardComponent {
user = input.required<User>();
selected = output<User>();
}@Injectable({ providedIn: 'root' })
export class UserService {
private http = inject(HttpClient);
getUsers(): Observable<User[]> {
return this.http.get<User[]>('/api/users');
}
}export class CounterComponent {
count = signal(0);
doubled = computed(() => this.count() * 2);
increment() {
this.count.update(c => c + 1);
}
}