---
name: "Angular"
description: "Always-on rules for writing modern Angular components, services, directives, pipes and routes."
applyTo: "**/*.component.ts,**/*.component.html,**/*.service.ts,**/*.directive.ts,**/*.pipe.ts,**/*.routes.ts"
---

# Angular rules

Write new code in the modern style (standalone, signals, `inject()`) even when older NgModule code sits alongside it.

## Components

- Use standalone components with `ChangeDetectionStrategy.OnPush` always. Fewer checks, predictable rendering.
- Use `input()`, `input.required()`, `output()` and `model()`; never `@Input()`/`@Output()` in new code.
- Use `inject()` in field initializers; keep the constructor empty. No `ngOnInit` for work a field initializer or `computed()` can do.
- Split smart and presentational: pages inject services and stores; everything else takes inputs and emits outputs.
- Use `viewChild()`/`contentChild()` signal queries instead of decorators.
- Put host bindings in `host: {}`, not `@HostBinding`/`@HostListener`.
- Keep components under about 200 lines; extract a child component or service beyond that.

## Signals and RxJS

- Hold state in `signal()`, derive with `computed()`; never store a derived value in a field.
- Update signals immutably (`items.update(l => [...l, x])`). Mutating in place does not notify.
- Use `effect()` only for side effects (storage, logging, third-party DOM); never write signals inside it. Use `computed()` or `linkedSignal()`.
- Use RxJS at the edges (HTTP, events, debouncing) and convert with `toSignal()` for templates.
- Never nest `subscribe()` calls; compose with `switchMap`, `concatMap` or `exhaustMap` and pick one deliberately.
- Clean up manual subscriptions with `takeUntilDestroyed()`. Prevents memory leaks.

## Templates

- Use `@if`, `@for` and `@switch`; always give `@for` a `track` on a stable id and an `@empty` branch.
- Keep logic out of templates: no method calls or complex expressions; read signals or `computed()` values.
- Use `@defer` for heavy, below-the-fold or interaction-gated content.
- Render loading, empty, error and success branches explicitly.
- Use semantic HTML or Angular Material/CDK; never a `div (click)`. Keyboard and screen-reader users need real controls.
- Never bind untrusted HTML with `[innerHTML]` from user data, and never call `bypassSecurityTrust*` on it. Prevents XSS.

## Services, HTTP and routing

- Provide services with `providedIn: 'root'` unless they must be scoped to a route or component.
- Make HTTP calls in services, typed with response interfaces; components never call `HttpClient` directly.
- Handle auth headers, errors and retries in functional interceptors, not in each call.
- Lazy load feature routes with `loadComponent`/`loadChildren`; use functional guards and resolvers.
- Bind route params with `withComponentInputBinding()` instead of subscribing to `ActivatedRoute`.
- Use typed reactive forms (`FormControl<string>`, `nonNullable`); no template-driven forms for complex input.
- Never put secrets in `environment.ts`; it ships to the browser.

## Types and tests

- Keep `strict` and `strictTemplates` on; no `any`, no `!` to silence errors.
- Test through the rendered DOM with component harnesses or Testing Library; mock HTTP with `provideHttpClientTesting()`.

Go deeper: for larger tasks use the angular-development, angular-architecture, angular-testing and angular-performance skills, and frontend-code-review before opening a pull request.
