49 lines | 2.8 KB

Angular — Claude Code rules

You are working in a modern Angular codebase. Follow the official Angular style guide (https://angular.dev/style-guide) and the patterns below.

Naming & files

  • Separate words in file names with hyphens: user-profile.ts, user-profile.html, user-profile.css.
  • A component's .ts, .html, and .css share the same base name; group them in one directory.
  • Unit tests end in .spec.ts and live next to the code under test.
  • Avoid generic file names like helpers.ts, utils.ts, or common.ts.
  • Organise by feature, not by file type (no components/ / services/ buckets). One concept per file.

Components

  • Components are standalone by default — add them directly to another component's imports array. Don't set standalone: false.
  • Group Angular-specific members (injected deps, inputs, outputs, queries) near the top, then methods.
  • Mark Angular-initialised properties readonly: input(), model(), output(), and query results.
  • Use protected for members only read from the template.
  • Keep components presentation-focused. Factor form validation and data transforms into separate functions/classes.
  • Directives reuse the same app-specific prefix as components; attribute selectors are camelCase (e.g. [mrTooltip]).
  • Keep lifecycle hooks short — call well-named methods from them; implement the hook interface (OnInit, etc.).

State / signals

  • Use signal(initial) for writable state; read by calling it: count(). Update with set(v) or update(fn).
  • Derive with computed(() => ...) — it's read-only, lazy, and memoised. Never .set()/.update() a computed.
  • Prefer a computed signal over complex template expressions.
  • Use effect() only for side effects on non-reactive APIs; don't write signals inside an effect.
  • Declare inputs with input() / input.required(), outputs with output(), two-way bindings with model().

Templates

  • Use built-in control flow: @if / @else, @switch / @case / @default, and @for@for requires a track (e.g. track item.id). Use @empty for the empty case.
  • Bind classes/styles with [class.x] and [style.prop], not NgClass / NgStyle.
  • Name event handlers for the action they perform, not the event: (click)="saveUserData()", not handleClick().

Dependency injection

  • Prefer the inject() function over constructor parameter injection — clearer with many deps and better inference.

Don't

  • Don't use *ngIf / *ngFor / *ngSwitch — use @if / @for / @switch.
  • Don't reach for NgClass / NgStyle when [class.*] / [style.*] will do.
  • Don't put long/complex logic in lifecycle hooks or template expressions.
  • Don't mutate readonly Angular-managed properties or write a computed signal.
  • When a rule conflicts with an existing file's style, prioritise consistency within that file.