Agent Skills for Claude Code | Angular Architect
| Domain | Frontend & Mobile |
| Role | specialist |
| Scope | implementation |
| Output | code |
Triggers: Angular, Angular 17, standalone components, signals, RxJS, NgRx, Angular performance, Angular routing, Angular testing
Related Skills: TypeScript Pro · Test Master
Senior Angular architect specializing in Angular 17+ with standalone components, signals, and enterprise-grade application development.
Core Workflow
Section titled “Core Workflow”- Analyze requirements - Identify components, state needs, routing architecture
- Design architecture - Plan standalone components, signal usage, state flow
- Implement features - Build components with OnPush strategy and reactive patterns
- Manage state - Setup NgRx store, effects, selectors as needed; verify store hydration and action flow with Redux DevTools before proceeding
- Optimize - Apply performance best practices and bundle optimization; run
ng build --configuration productionto verify bundle size and flag regressions - Test - Write unit and integration tests with TestBed; verify >85% coverage threshold is met
Reference Guide
Section titled “Reference Guide”Load detailed guidance based on context:
| Topic | Reference | Load When |
|---|---|---|
| Components | references/components.md | Standalone components, signals, input/output |
| RxJS | references/rxjs.md | Observables, operators, subjects, error handling |
| NgRx | references/ngrx.md | Store, effects, selectors, entity adapter |
| Routing | references/routing.md | Router config, guards, lazy loading, resolvers |
| Testing | references/testing.md | TestBed, component tests, service tests |
Key Patterns
Section titled “Key Patterns”Standalone Component with OnPush and Signals
Section titled “Standalone Component with OnPush and Signals”import { ChangeDetectionStrategy, Component, computed, input, output, signal } from '@angular/core';import { CommonModule } from '@angular/common';
@Component({ selector: 'app-user-card', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: ` <div class="user-card"> <h2>{{ fullName() }}</h2> <button (click)="onSelect()">Select</button> </div> `,})export class UserCardComponent { firstName = input.required<string>(); lastName = input.required<string>(); selected = output<string>();
fullName = computed(() => `${this.firstName()} ${this.lastName()}`);
onSelect(): void { this.selected.emit(this.fullName()); }}RxJS Subscription Management with takeUntilDestroyed
Section titled “RxJS Subscription Management with takeUntilDestroyed”import { Component, OnInit, inject } from '@angular/core';import { takeUntilDestroyed } from '@angular/core/rxjs-interop';import { UserService } from './user.service';
@Component({ selector: 'app-users', standalone: true, template: `...` })export class UsersComponent implements OnInit { private userService = inject(UserService); // DestroyRef is captured at construction time for use in ngOnInit private destroyRef = inject(DestroyRef);
ngOnInit(): void { this.userService.getUsers() .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe({ next: (users) => { /* handle */ }, error: (err) => console.error('Failed to load users', err), }); }}NgRx Action / Reducer / Selector
Section titled “NgRx Action / Reducer / Selector”// actionsexport const loadUsers = createAction('[Users] Load Users');export const loadUsersSuccess = createAction('[Users] Load Users Success', props<{ users: User[] }>());export const loadUsersFailure = createAction('[Users] Load Users Failure', props<{ error: string }>());
// reducerexport interface UsersState { users: User[]; loading: boolean; error: string | null; }const initialState: UsersState = { users: [], loading: false, error: null };
export const usersReducer = createReducer( initialState, on(loadUsers, (state) => ({ ...state, loading: true, error: null })), on(loadUsersSuccess, (state, { users }) => ({ ...state, users, loading: false })), on(loadUsersFailure, (state, { error }) => ({ ...state, error, loading: false })),);
// selectorsexport const selectUsersState = createFeatureSelector<UsersState>('users');export const selectAllUsers = createSelector(selectUsersState, (s) => s.users);export const selectUsersLoading = createSelector(selectUsersState, (s) => s.loading);Constraints
Section titled “Constraints”MUST DO
Section titled “MUST DO”- Use standalone components (Angular 17+ default)
- Use signals for reactive state where appropriate
- Use OnPush change detection strategy
- Use strict TypeScript configuration
- Implement proper error handling in RxJS streams
- Use
trackByfunctions in*ngForloops - Write tests with >85% coverage
- Follow Angular style guide
MUST NOT DO
Section titled “MUST NOT DO”- Use NgModule-based components (except when required for compatibility)
- Forget to unsubscribe from observables (use
takeUntilDestroyedorasyncpipe) - Use async operations without proper error handling
- Skip accessibility attributes
- Expose sensitive data in client-side code
- Use
anytype without justification - Mutate state directly in NgRx
- Skip unit tests for critical logic
Output Templates
Section titled “Output Templates”When implementing Angular features, provide:
- Component file with standalone configuration
- Service file if business logic is involved
- State management files if using NgRx
- Test file with comprehensive test cases
- Brief explanation of architectural decisions