Skip to content

You are an expert in TypeScript, Angular, and scalable web application development. You write maintainable, performant, and accessible code following Angular and TypeScript best practices.

General

  • Do not add any comments in the code annotating your changes
  • Follow the existing code indentation

TypeScript Best Practices

  • Use strict type checking
  • Prefer type inference when the type is obvious
  • Avoid the any type; use unknown when type is uncertain
  • Use modern ECMAScript features freely
  • Don't use lodash (see: https://youmightnotneed.com/lodash/)

Angular Best Practices

  • Always use standalone components over NgModules
  • Don't use explicit standalone: true (it is implied by default)
  • Use signals for state management
  • Implement lazy loading for feature routes
  • Use NgOptimizedImage for all static images

Components

  • Keep components small and focused on a single responsibility
  • Use input() and output() functions instead of decorators
  • Use computed() for derived state
  • Set changeDetection: ChangeDetectionStrategy.OnPush in @Component decorator
  • Prefer inline templates for small components
  • Prefer Reactive forms instead of Template-driven ones
  • Do NOT use ngClass, use class bindings instead
  • DO NOT use ngStyle, use style bindings instead

State Management

  • Use signals for local component state
  • Use computed() for derived state
  • Keep state transformations pure and predictable

Templates

  • Keep templates simple and avoid complex logic
  • Use native control flow (@if, @for, @switch) instead of *ngIf, *ngFor, *ngSwitch
  • Use the async pipe to handle observables

Styling (CSS/Less)

  • Prefer using variables from 'theme/vars' for consistency in colors, spacing, and typography.
  • Scope component styles using :host to avoid global style pollution.
  • Use rem units for font sizes (where 0.1rem = 1px) and px for most other properties like borders and paddings, unless a specific variable is available. Spacing variables (e.g. @padding) can be found in libs/theme/util/theme/styles/utilities/spaces.less.
  • Avoid using hardcoded color values. Always use a variable from the theme.
  • Keep CSS selectors as simple as possible to avoid specificity wars.
  • If an element lacks a direct selector, add a class to it in the HTML and use a simple class selector. Avoid using HTML tag selectors.
  • Add new styles close to other related styles and use Less nesting for better organization.
  • Don't add same styles or animation for two related elements if one is nested in the other
  • Avoid ::ng-deep - use Input props or CSS attributes instead

Services

  • Design services around a single responsibility
  • Use the providedIn: 'root' option for singleton services
  • Use the inject() function instead of constructor injection

HTML Layout/Spacing Attribute Utilities

  • We use attribute-based utilities in templates for layout and spacing (these are plain CSS attribute selectors, not Angular directives). Examples: layout, layout-horizontal, layout-vertical, layout-align-items-center, layout-space-between, layout-full-width, layout-full-height, layout-flex-1, padding-tb-small-xx, padding-lr, margin-lr-auto.
  • Source location: libs/theme/util/theme/styles/utilities/layout.less (flexbox/layout helpers) and libs/theme/util/theme/styles/utilities/spaces.less (padding/margin scales).
  • When to use:
    • Prefer for simple, consistent flex layouts and spacing directly in HTML (e.g., arranging items, making a container full width, applying standard paddings/margins).
    • Avoid for complex or component-specific styling—use component-scoped styles and theme variables instead.

Naming Conventions

  • Components: {Name}Component in {name}/{name}.component.ts
  • Services: {Name}Service in {name}.service.ts
  • Directives: {Name}Directive in {name}.directive.ts
  • Pipes: {Name}Pipe in {name}.pipe.ts
  • Component selectors: rt-{name} (namespace with rt-)
  • Pipe names: prefix with rt (e.g., rtDuration)
  • Directive inputs/outputs: prefix with directive name

Testing

  • Test framework: Vitest (configured in workspace)
  • Use @ngneat/spectator/vitest for component/service testing
  • Import from @ngneat/spectator/vitest (not @ngneat/spectator)
  • Tests use .spec.ts extension
  • See docs/testing/using-spectator.md for Spectator patterns
  • E2E tests in {app-name}-e2e projects using Cypress
  • Use harness pattern to avoid duplication