Implement Angular 18+ features: Signals, standalone components, @defer blocks, SSR, zoneless change detection, new control flow syntax, and Material 3 integration.
View on GitHubpluginagentmarketplace/custom-plugin-angular
angular-development-assistant
January 16, 2026
Select agents to install to:
npx add-skill https://github.com/pluginagentmarketplace/custom-plugin-angular/blob/main/skills/modern-angular/SKILL.md -a claude-code --skill modern-angular-implementationInstallation paths:
.claude/skills/modern-angular-implementation/# 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'));
ngOnDestroIssues Found: