Back to Skills

modern-angular-implementation

verified

Implement Angular 18+ features: Signals, standalone components, @defer blocks, SSR, zoneless change detection, new control flow syntax, and Material 3 integration.

View on GitHub

Marketplace

pluginagentmarketplace-angular

pluginagentmarketplace/custom-plugin-angular

Plugin

angular-development-assistant

Repository

pluginagentmarketplace/custom-plugin-angular
2stars

skills/modern-angular/SKILL.md

Last Verified

January 16, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/pluginagentmarketplace/custom-plugin-angular/blob/main/skills/modern-angular/SKILL.md -a claude-code --skill modern-angular-implementation

Installation paths:

Claude
.claude/skills/modern-angular-implementation/
Powered by add-skill CLI

Instructions

# Modern Angular Implementation Skill

## Angular Signals

### Basic Signals
```typescript
import { Component, signal, computed, effect } from '@angular/core';

@Component({
  selector: 'app-counter',
  standalone: true,
  template: `
    <button (click)="increment()">{{ count() }}</button>
    <p>Double: {{ double() }}</p>
  `
})
export class CounterComponent {
  // Writable signal
  count = signal(0);

  // Computed signal (auto-updates)
  double = computed(() => this.count() * 2);

  constructor() {
    // Effect (side effects)
    effect(() => {
      console.log('Count changed:', this.count());
    });
  }

  increment() {
    this.count.update(n => n + 1);
    // or: this.count.set(this.count() + 1);
  }
}
```

### Signal Store Pattern
```typescript
@Injectable({ providedIn: 'root' })
export class UserStore {
  // Private state signal
  private state = signal<{
    users: User[];
    loading: boolean;
    error: string | null;
  }>({
    users: [],
    loading: false,
    error: null
  });

  // Public computed selectors
  readonly users = computed(() => this.state().users);
  readonly loading = computed(() => this.state().loading);
  readonly error = computed(() => this.state().error);
  readonly userCount = computed(() => this.users().length);

  // Actions
  async loadUsers() {
    this.state.update(s => ({ ...s, loading: true }));
    try {
      const users = await this.http.get<User[]>('/api/users');
      this.state.update(s => ({ ...s, users, loading: false }));
    } catch (error) {
      this.state.update(s => ({
        ...s,
        error: error.message,
        loading: false
      }));
    }
  }

  addUser(user: User) {
    this.state.update(s => ({
      ...s,
      users: [...s.users, user]
    }));
  }
}
```

### Signals vs RxJS
```typescript
// ❌ OLD: RxJS BehaviorSubject
private userSubject = new BehaviorSubject<User | null>(null);
user$ = this.userSubject.asObservable();
userName$ = this.user$.pipe(map(u => u?.name ?? 'Guest'));

ngOnDestro

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
11508 chars

Issues Found:

  • name_directory_mismatch