Install Angular Core
Pick your agent. Every command is ready to paste.
npx skills add Gentleman-Programming/Gentleman-Skills --skill angular-coreThe open skills CLI detects your agents (Claude Code, Cursor, Codex and 70+ more) and installs to the right folder. Add -g to install globally.
01
Install it
Run the command above, or upload the folder in Claude.
02
Ask naturally
Describe the task. Your agent loads angular-core when the request matches its description.
03
Name it if needed
If it does not trigger, say “use the angular-core skill”. In Codex, type $angular-core.
Standalone Components (REQUIRED)
Components are standalone by default. Do NOT set standalone: true.
@Component({
selector: 'app-user',
imports: [CommonModule],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `...`
})
export class UserComponent {}
Input/Output Functions (REQUIRED)
// ✅ ALWAYS: Function-based
readonly user = input.required<User>();
readonly disabled = input(false);
readonly selected = output<User>();
readonly checked = model(false); // Two-way binding
// ❌ NEVER: Decorators
@Input() user: User;
@Output() selected = new EventEmitter<User>();
Signals for State (REQUIRED)
readonly count = signal(0);
readonly doubled = computed(() => this.count() * 2);
// Update
this.count.set(5);
this.count.update(prev => prev + 1);
// Side effects
effect(() => localStorage.setItem('count', this.count().toString()));
NO Lifecycle Hooks (REQUIRED)
Signals replace lifecycle hooks. Do NOT use ngOnInit, ngOnChanges, ngOnDestroy.
// ❌ NEVER: Lifecycle hooks
ngOnInit() {
this.loadUser();
}
ngOnChanges(changes: SimpleChanges) {
if (changes['userId']) {
this.loadUser();
}
}
// ✅ ALWAYS: Signals + effect
readonly userId = input.required<string>();
readonly user = signal<User | null>(null);
private userEffect = effect(() => {
// Runs automatically when userId() changes
this.loadUser(this.userId());
});
// ✅ For derived data, use computed
readonly displayName = computed(() => this.user()?.name ?? 'Guest');
When to Use What
| Need | Use |
|---|---|
| React to input changes | effect() watching the input signal |
| Derived/computed state | computed() |
| Side effects (API calls, localStorage) | effect() |
| Cleanup on destroy | DestroyRef + inject() |
// Cleanup example
private readonly destroyRef = inject(DestroyRef);
constructor() {
const subscription = someObservable$.subscribe();
this.destroyRef.onDestroy(() => subscription.unsubscribe());
}
inject() Over Constructor (REQUIRED)
// ✅ ALWAYS
private readonly http = inject(HttpClient);
// ❌ NEVER
constructor(private http: HttpClient) {}
Native Control Flow (REQUIRED)
@if (loading()) {
<spinner />
} @else {
@for (item of items(); track item.id) {
<item-card [data]="item" />
} @empty {
<p>No items</p>
}
}
@switch (status()) {
@case ('active') { <span>Active</span> }
@default { <span>Unknown</span> }
}
RxJS - Only When Needed
Signals are the default. Use RxJS ONLY for complex async operations.
| Use Signals | Use RxJS |
|---|---|
| Component state | Combining multiple streams |
| Derived values | Debounce/throttle |
| Simple async (single API call) | Race conditions |
| Input/Output | WebSockets, real-time |
| Complex error retry logic |
// ✅ Simple API call - use signals
readonly user = signal<User | null>(null);
readonly loading = signal(false);
async loadUser(id: string) {
this.loading.set(true);
this.user.set(await firstValueFrom(this.http.get<User>(`/api/users/${id}`)));
this.loading.set(false);
}
// ✅ Complex stream - use RxJS
readonly searchResults$ = this.searchTerm$.pipe(
debounceTime(300),
distinctUntilChanged(),
switchMap(term => this.http.get<Results>(`/api/search?q=${term}`))
);
// Convert to signal when needed in template
readonly searchResults = toSignal(this.searchResults$, { initialValue: [] });
Zoneless Angular (REQUIRED)
Angular is zoneless. Use provideZonelessChangeDetection().
bootstrapApplication(AppComponent, {
providers: [provideZonelessChangeDetection()]
});
Remove ZoneJS:
npm uninstall zone.js
Remove from angular.json polyfills: zone.js and zone.js/testing.
Zoneless Requirements
- Use
OnPushchange detection - Use signals for state (auto-notifies Angular)
- Use
AsyncPipefor observables - Use
markForCheck()when needed
Resources
Tips for Angular Core
- • Start a fresh session after installing so your agent picks up the new skill.
- • It is part of a pack with 24 skills. Install only the ones you need with --skill to keep triggers precise.
- • If two skills overlap, mention the one you want by name.
Questions about Angular Core
What does the Angular Core skill do?
Angular core patterns: standalone components, signals, inject, control flow, zoneless. Trigger: When creating Angular components, using signals, or setting up zoneless.
How do I install Angular Core?
Run "npx skills add Gentleman-Programming/Gentleman-Skills --skill angular-core" in your project. The skills CLI installs it for Claude Code, Cursor, Codex and 70+ other agents. In Claude on the web, upload the skill folder as a ZIP under Customize > Skills.
Does Angular Core work in Cursor and Codex?
Yes. Angular Core uses the open SKILL.md format, so it works in Claude Code, Claude, Cursor, OpenAI Codex, Gemini CLI, GitHub Copilot and other agents that support agent skills.
Is Angular Core free?
Angular Core is open source on GitHub under the MIT license. It is free to install; check the license before commercial use.
Who made Angular Core?
Angular Core is published by Gentleman-Programming in the Gentleman-Programming/Gentleman-Skills repository, together with 23 other skills.




