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.cssshare the same base name; group them in one directory. - Unit tests end in
.spec.tsand live next to the code under test. - Avoid generic file names like
helpers.ts,utils.ts, orcommon.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
importsarray. Don't setstandalone: 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
protectedfor 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;
implementthe hook interface (OnInit, etc.).
State / signals
- Use
signal(initial)for writable state; read by calling it:count(). Update withset(v)orupdate(fn). - Derive with
computed(() => ...)— it's read-only, lazy, and memoised. Never.set()/.update()a computed. - Prefer a
computedsignal 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 withoutput(), two-way bindings withmodel().
Templates
- Use built-in control flow:
@if/@else,@switch/@case/@default, and@for—@forrequires atrack(e.g.track item.id). Use@emptyfor the empty case. - Bind classes/styles with
[class.x]and[style.prop], notNgClass/NgStyle. - Name event handlers for the action they perform, not the event:
(click)="saveUserData()", nothandleClick().
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/NgStylewhen[class.*]/[style.*]will do. - Don't put long/complex logic in lifecycle hooks or template expressions.
- Don't mutate
readonlyAngular-managed properties or write a computed signal. - When a rule conflicts with an existing file's style, prioritise consistency within that file.