skillZs
★ LIVE SKILL TAGS ★
>>> LIVE SKILLS INDEX <<<
* OPEN SOURCE *
NO LOGIN, NO TRACKING
※ REAL INSTALL DATA ※
← back to all skills
gentleman-programming/gentleman-skills217 installs

angular-core

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 this agent skill?

npx skills add https://github.com/gentleman-programming/gentleman-skills --skill angular-core
view source ↗

Is this agent skill safe to install?

  • Gen Agent Trust Hubpass

    The skill provides architectural guidelines and coding standards for modern Angular development, covering signals, standalone components, and zoneless configurations. No security issues or malicious patterns were detected.

  • Socketpass

    No alerts

  • Snykpass

    Risk: LOW · No issues

  • Runlayerwarn

    1/1 file flagged

What does this agent skill do?

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

NeedUse
React to input changeseffect() watching the input signal
Derived/computed statecomputed()
Side effects (API calls, localStorage)effect()
Cleanup on destroyDestroyRef + 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 SignalsUse RxJS
Component stateCombining multiple streams
Derived valuesDebounce/throttle
Simple async (single API call)Race conditions
Input/OutputWebSockets, 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 OnPush change detection
  • Use signals for state (auto-notifies Angular)
  • Use AsyncPipe for observables
  • Use markForCheck() when needed

Resources

Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.

<a href="https://skillzs.dev/skills/gentleman-programming/gentleman-skills/angular-core">View angular-core on skillZs</a>