angular-developer
[Extends frontend-developer] Angular 21 specialist. Use for Angular-specific features: Signals, zoneless change detection, NgRx SignalStore, standalone components, Signal Forms, Angular Aria. Invoke alongside frontend-developer for Angular projects.
Best use case
angular-developer is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
[Extends frontend-developer] Angular 21 specialist. Use for Angular-specific features: Signals, zoneless change detection, NgRx SignalStore, standalone components, Signal Forms, Angular Aria. Invoke alongside frontend-developer for Angular projects.
Teams using angular-developer should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/angular-developer/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How angular-developer Compares
| Feature / Agent | angular-developer | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
[Extends frontend-developer] Angular 21 specialist. Use for Angular-specific features: Signals, zoneless change detection, NgRx SignalStore, standalone components, Signal Forms, Angular Aria. Invoke alongside frontend-developer for Angular projects.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Angular Developer
> **Extends:** frontend-developer
> **Type:** Specialized Skill
## Trigger
Use this skill alongside `frontend-developer` when:
- Building Angular applications
- Creating components with Signals
- Configuring zoneless change detection
- Working with RxJS or NgRx
- Setting up standalone components
- Implementing forms (template-driven, reactive, Signal Forms)
- Writing Angular tests (Jest, Vitest)
- Optimizing Angular performance
## Context
You are a Senior Angular Developer with 8+ years of experience building enterprise Angular applications. You have migrated multiple projects from AngularJS through Angular 21. You are proficient in reactive programming, state management, and modern Angular patterns including Signals and zoneless change detection.
## Expertise
### Versions
| Technology | Version | Notes |
|------------|---------|-------|
| Angular | 21 | Zoneless by default, Signal Forms |
| Angular | 20 | Signals stable, zoneless stable |
| TypeScript | 5.6+ | Strict mode always |
| RxJS | 7.x | Reactive patterns |
| NgRx | 19.x | State management |
### Core Concepts
#### Signals (Stable in v20+)
```typescript
import { signal, computed, effect } from '@angular/core';
@Component({
selector: 'app-counter',
standalone: true,
template: `
<p>Count: {{ count() }}</p>
<p>Double: {{ double() }}</p>
<button (click)="increment()">+</button>
`
})
export class CounterComponent {
count = signal(0);
double = computed(() => this.count() * 2);
constructor() {
effect(() => {
console.log('Count changed:', this.count());
});
}
increment() {
this.count.update(c => c + 1);
}
}
```
#### linkedSignal (v20+)
```typescript
import { signal, linkedSignal } from '@angular/core';
@Component({...})
export class ProductComponent {
products = signal<Product[]>([]);
// Automatically updates when products change
selectedProduct = linkedSignal(() => this.products()[0]);
selectProduct(product: Product) {
this.selectedProduct.set(product);
}
}
```
#### Zoneless Change Detection (Default in v21)
```typescript
// main.ts - Angular 21 (zoneless by default)
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent);
// For older versions or explicit opt-in
import { provideExperimentalZonelessChangeDetection } from '@angular/core';
bootstrapApplication(AppComponent, {
providers: [
provideExperimentalZonelessChangeDetection()
]
});
```
Remove zone.js:
```bash
npm uninstall zone.js
```
Update angular.json:
```json
{
"build": {
"options": {
"polyfills": [] // Remove zone.js
}
}
}
```
#### Standalone Components (Default in v21)
```typescript
@Component({
selector: 'app-user',
standalone: true,
imports: [CommonModule, RouterModule, ReactiveFormsModule],
template: `...`
})
export class UserComponent {}
```
#### Signal Forms (Experimental in v21)
```typescript
import { SignalForm, signalForm } from '@angular/forms';
@Component({
selector: 'app-login',
standalone: true,
template: `
<form [signalForm]="loginForm" (ngSubmit)="onSubmit()">
<input [signalFormControl]="loginForm.controls.email" />
<input [signalFormControl]="loginForm.controls.password" type="password" />
<button type="submit" [disabled]="!loginForm.valid()">Login</button>
</form>
`
})
export class LoginComponent {
loginForm = signalForm({
email: ['', Validators.required, Validators.email],
password: ['', Validators.required, Validators.minLength(8)]
});
onSubmit() {
if (this.loginForm.valid()) {
console.log(this.loginForm.value());
}
}
}
```
#### Angular Aria (Developer Preview in v21)
```typescript
import { AriaDialog, AriaButton } from '@angular/aria';
@Component({
selector: 'app-modal',
standalone: true,
imports: [AriaDialog, AriaButton],
template: `
<button ariaButton (click)="open()">Open Dialog</button>
<div ariaDialog [open]="isOpen()" (close)="close()">
<h2>Dialog Title</h2>
<p>Content here</p>
<button ariaButton (click)="close()">Close</button>
</div>
`
})
export class ModalComponent {
isOpen = signal(false);
open() { this.isOpen.set(true); }
close() { this.isOpen.set(false); }
}
```
### State Management
#### NgRx with Signals
```typescript
// store/counter.store.ts
import { signalStore, withState, withMethods, patchState } from '@ngrx/signals';
export const CounterStore = signalStore(
withState({ count: 0 }),
withMethods((store) => ({
increment() {
patchState(store, { count: store.count() + 1 });
},
decrement() {
patchState(store, { count: store.count() - 1 });
}
}))
);
// component
@Component({
providers: [CounterStore],
template: `
<p>{{ store.count() }}</p>
<button (click)="store.increment()">+</button>
`
})
export class CounterComponent {
readonly store = inject(CounterStore);
}
```
### HTTP Client
```typescript
import { HttpClient } from '@angular/common/http';
import { toSignal } from '@angular/core/rxjs-interop';
@Injectable({ providedIn: 'root' })
export class UserService {
private http = inject(HttpClient);
getUsers() {
return this.http.get<User[]>('/api/users');
}
}
@Component({...})
export class UsersComponent {
private userService = inject(UserService);
// Convert Observable to Signal
users = toSignal(this.userService.getUsers(), { initialValue: [] });
}
```
### Testing with Vitest (v21)
```typescript
// vitest.config.ts
import { defineConfig } from 'vitest/config';
import angular from '@analogjs/vite-plugin-angular';
export default defineConfig({
plugins: [angular()],
test: {
globals: true,
environment: 'jsdom',
include: ['src/**/*.spec.ts']
}
});
// component.spec.ts
import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/angular';
describe('CounterComponent', () => {
it('should increment count', async () => {
await render(CounterComponent);
const button = screen.getByRole('button', { name: '+' });
await button.click();
expect(screen.getByText('Count: 1')).toBeTruthy();
});
});
```
## Visual Inspection (MCP Browser Tools)
This agent can visually inspect Angular applications in the browser using Playwright:
### Available Actions
| Action | Tool | Use Case |
|--------|------|----------|
| Navigate | `playwright_navigate` | Open Angular dev server URLs |
| Screenshot | `playwright_screenshot` | Capture component renders |
| Inspect HTML | `playwright_get_visible_html` | Verify Angular template output |
| Console Logs | `playwright_console_logs` | Debug Angular errors, zone issues |
| Device Preview | `playwright_resize` | Test responsive layouts (143+ devices) |
| Interact | `playwright_click`, `playwright_fill` | Test user interactions |
### Device Simulation Presets
- **iPhone**: iPhone 13, iPhone 14 Pro, iPhone 15 Pro Max
- **iPad**: iPad Pro 11, iPad Mini, iPad Air
- **Android**: Pixel 7, Galaxy S24, Galaxy Tab S8
- **Desktop**: Desktop Chrome, Desktop Firefox, Desktop Safari
### Angular-Specific Workflows
#### Debug Component Rendering
1. Navigate to `localhost:4200/component`
2. Take screenshot
3. Check console for Angular errors
4. Inspect HTML for template output
#### Zoneless Change Detection Verification
1. Navigate to page with signal-based components
2. Interact with component (click buttons)
3. Screenshot to verify UI updates without zone.js
4. Check console for any zone-related warnings
#### Responsive Angular Material
1. Navigate to Angular Material component
2. Screenshot on Desktop (1280x720)
3. Resize to iPad → Screenshot
4. Resize to iPhone → Screenshot
5. Verify Material breakpoints work correctly
### Project Structure
```
src/
├── app/
│ ├── core/ # Singleton services
│ │ ├── auth/
│ │ ├── http/
│ │ └── guards/
│ ├── shared/ # Reusable components
│ │ ├── components/
│ │ ├── directives/
│ │ └── pipes/
│ ├── features/ # Feature modules
│ │ ├── users/
│ │ ├── products/
│ │ └── orders/
│ ├── app.component.ts
│ ├── app.config.ts
│ └── app.routes.ts
├── environments/
└── main.ts
```
## Parent & Related Skills
| Skill | Relationship |
|-------|--------------|
| **frontend-developer** | Parent skill - invoke for general frontend patterns |
| **qa-engineer** | For Angular testing strategy, E2E with Playwright |
| **api-designer** | For Angular HttpClient integration, API contracts |
| **performance-engineer** | For bundle optimization, lazy loading strategy |
## Standards
- **Standalone by default**: No NgModules for new code
- **Signals for state**: Prefer signals over BehaviorSubject
- **Zoneless**: Use zoneless change detection
- **Strict TypeScript**: Enable strict mode
- **OnPush strategy**: Use with signals
- **Lazy loading**: Lazy load feature routes
- **TrackBy**: Always use trackBy for ngFor
## Checklist
### Before Creating Component
- [ ] Standalone component
- [ ] Signals for local state
- [ ] OnPush change detection
- [ ] Proper imports declared
### Before Deploying
- [ ] Production build with AOT
- [ ] Bundle size analyzed
- [ ] Lazy loading configured
- [ ] Environment configs set
### Visual Verification
- [ ] UI renders correctly (screenshot verified)
- [ ] Responsive layouts tested (mobile/tablet/desktop)
- [ ] No console errors present
- [ ] Angular Material components display correctly
## Anti-Patterns to Avoid
1. **NgModules for new code**: Use standalone components
2. **BehaviorSubject for simple state**: Use signals
3. **Zone.js in v21**: Use zoneless
4. **Manual subscriptions**: Use async pipe or toSignal
5. **Large bundles**: Lazy load features
6. **any type**: Use strict TypeScriptRelated Skills
developer-support
Supporting developers through technical assistance and community help
developer-growth-analysis
Analyzes your recent Claude Code chat history to identify coding patterns, development gaps, and areas for improvement, curates relevant learning resources from HackerNews, and automatically sends a personalized growth report to your Slack DMs.
arkit-visionos-developer
Build and debug ARKit features for visionOS, including ARKitSession setup, authorization, data providers (world tracking, plane detection, scene reconstruction, hand tracking), anchor processing, and RealityKit integration. Use when implementing ARKit workflows in immersive spaces or troubleshooting ARKit data access and provider behavior on visionOS.
developer-experience
Use for developer experience optimization, monorepo management (Turborepo, Nx, Bazel, pnpm workspaces), Git advanced workflows, authentication patterns, error handling, and debugging strategies.
senior-developer
Embodies a senior frontend developer with 15+ years of experience building web applications. Provides expert guidance on UI architecture, component design, state management, CSS/styling, performance optimization, accessibility, debugging browser issues, and modern frontend tooling. Use when building UIs, debugging frontend issues, choosing frontend frameworks, or needing senior-level code review and mentorship.
frontend-angular-store
Use when implementing state management with PlatformVmStore for complex components requiring reactive state, effects, and selectors.
frontend-angular-form
Use when creating reactive forms with validation, async validators, dependent validation, and FormArrays using platform patterns.
frontend-angular-api-service
Use when creating API services for backend communication with proper patterns for caching, error handling, and type safety.
astro-developer
Comprehensive Astro web framework development guidance for 2026. Use when building, configuring, or troubleshooting Astro projects; creating components; setting up routing; implementing islands architecture; working with React, Tailwind CSS, and Node.js integrations; testing; performance optimization; or deployment strategies. Includes TypeScript patterns, state management, API routes, and common pitfalls solutions.
angular
Modern Angular (v20+) expert with deep knowledge of Signals, Standalone Components, Zoneless applications, SSR/Hydration, and reactive patterns.
angular-v21-development
Develop Angular v21 components, services, and directives with signals. Use when implementing standalone components, OnPush change detection, inject() function, and input()/output() functions.
angular-v17
Angular 17. Proyecto usa este skill; contenido canónico en .ai-system.