angular-conventions

Installation
SKILL.md

Angular conventions

These are house rules for Angular, floored at v17 and reaching forward to whatever the workspace is actually on (v20, v21, v22). When a newer idiom exists, prefer it - but only adopt one the installed version ships. The language underneath (strict TypeScript, type modeling, modules, async, error handling, lint and format) is owned by typescript; load it next to this skill and assume everything here is purely Angular. Material components and the CDK are angular-material; the broader web index is frontend; Ionic and Capacitor are mobile. This file is opinion, not reference: it states the choices the team has settled on and the divergences kept on purpose. For any API surface not pinned down here, reach for the Angular CLI MCP or angular.dev rather than memory. Version specifics live in per-version delta files - load only the one your workspace is on: references/v22.md, v21.md, v20.md, or v19.md (fact-checked against angular.dev). Each states what is stable versus still experimental in that version, its version-specific API spellings and deprecations, and its Node.js/TypeScript requirement; the rest of this file applies across all of v19-v22.

The enforceable config and the v20+ file-naming rules live in references/angular-style.md - the angular-eslint + Prettier flat config, the drop-suffix file names, and modern-vs-legacy examples. Above these general conventions, a project's own config (eslint.config.js, angular.json, .prettierrc, .editorconfig) and its docs/PROJECT-CODE-STYLE.md are higher priority: follow the project where it diverges.

Standalone is the only module model

  • Every component, directive, and pipe is standalone - the implicit default from v19, declared explicitly before that. NgModule does not appear in new code; the bootstrap is bootstrapApplication with an ApplicationConfig.
  • A component pulls in exactly what its template uses via imports. No grab-bag shared module re-exporting half the framework.
  • File names follow the v20 style guide: drop the type suffix for components, directives, services, and pipes. OrderList lives in order-list.ts (not order-list.component.ts), with order-list.html / order-list.css sharing the base name; guards, resolvers, interceptors, and modules keep a role word on the class but hyphenate the file (auth-guard.ts, not auth.guard.ts). v19 and earlier keep the classic .component/.service suffix, so a workspace on v19 stays on it and ng update preserves suffix generation - migrate organically, do not mass-rename. Full naming table in references/angular-style.md.
  • One responsibility per file. Template and styles live beside the class in the same folder; inline them only for genuinely trivial components. How those styles are scoped and architected - ViewEncapsulation, :host, design tokens, responsive, a11y styling - is angular-styling.
  • Selectors are kebab-case with the project prefix - app-order-list, never a bare order-list that risks colliding with a third-party tag.
  • Keep the container-versus-presentational split honest: containers own data fetching and state, presentational components take inputs and emit outputs and hold no service of their own.

Signals are the default state primitive

  • Local component state is a signal; anything derived is a computed; side effects that must react to state run in an effect. Reach for this before any other mechanism in new code.
  • Any state a computed or an effect reads must itself be a signal. A plain class property that feeds a derived value is the reactivity bug to hunt: the computed reads it once at creation and never recomputes when the property later changes, so a filter/derived view silently stops updating until some unrelated change happens to trigger change detection. If a computed depends on it, it is a signal - no exceptions; a filter field, a selected id, a search term that narrows a list all qualify.
Installs
9
GitHub Stars
1
First Seen
Jun 21, 2026
angular-conventions — envoydev/claude-stack