cli/templates/skills/frontend-angular/SKILL.md
Angular (v17+) frontend development conventions. Use when working on Angular projects.
npx skillsauth add binhtranquoc/agent-kit-skill frontend-angularInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill provides specific conventions for Angular 17+ development using Modern Angular features.
project-standards skillAlways use standalone: true. Avoid NgModules unless integrating legacy libraries.
import { Component, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-user-profile',
standalone: true,
imports: [CommonModule],
template: `
<div class="profile">
<h1>{{ name() }}</h1>
<button (click)="updateName()">Update</button>
</div>
`,
styles: [`
.profile { padding: 1rem; }
`]
})
export class UserProfileComponent {
name = signal('John Doe');
updateName() {
this.name.set('Jane Doe');
}
}
Use signal, computed, and effect instead of RxJS for synchronous state.
import { Component, signal, computed } from '@angular/core';
@Component({ ... })
export class CounterComponent {
count = signal(0);
doubleCount = computed(() => this.count() * 2);
increment() {
this.count.update(n => n + 1);
}
}
Use the new built-in control flow (@if, @for, @switch).
@if (isLoggedIn()) {
<user-dashboard />
} @else {
<login-form />
}
<ul>
@for (user of users(); track user.id) {
<li>{{ user.name }}</li>
} @empty {
<li>No users found.</li>
}
</ul>
Use inject() function instead of constructor injection.
import { Component, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({ ... })
export class DataComponent {
private http = inject(HttpClient);
data$ = this.http.get('/api/data');
}
inject services), manage state, pass data down.@Input, emit @Output, no side effects.Use input() (Signal Inputs) and output().
import { Component, input, output } from '@angular/core';
@Component({ ... })
export class ChildComponent {
// Signal Input (Read-only signal)
title = input.required<string>(); // required
count = input(0); // optional with default
// Output
changed = output<number>();
emitChange() {
this.changed.emit(10);
}
}
For most apps, use Services with Signals.
import { Injectable, signal } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class CartService {
private items = signal<Item[]>([]);
readonly cartItems = this.items.asReadonly();
addItem(item: Item) {
this.items.update(current => [...current, item]);
}
}
src/
app/
core/ # Singleton services, interceptors, guards
shared/ # Reusable UI components, pipes, directives
features/ # Feature modules/folders (e.g., users, products)
users/
users.routes.ts
user-list/
user-detail/
app.routes.ts
app.config.ts
app.component.ts
development
Activate Code Reviewer mode for code review and quality assurance. Use when reviewing code for bugs, security issues, or optimization opportunities.
development
Default Implementer mode for writing production code. Use for general coding tasks following project conventions.
development
Activate Debugger mode for systematic bug fixing. Use when debugging errors, investigating issues, or fixing bugs.
testing
Activate Architect mode for system design and architecture decisions. Use when planning features, designing systems, or making architectural choices.