Angular Code Review Rules
Security (Critical)
- Template Safety: Never interpolate untrusted user input into templates (
{{ }}) without escaping or sanitizing using Angular's built-in mechanisms (DomSanitizer APIs). Always validate and escape any dynamic input before rendering - [innerHTML] Binding: If using
[innerHTML], always sanitize input with DomSanitizer and add a code comment explaining why. Never bind raw user input directly - DomSanitizer Usage: Use
DomSanitizeronly after rigorous validation. Example safe usage:// Safe: Sanitized HTML from trusted CMS after validation this.sanitizedContent = this.sanitizer.sanitize(SecurityContext.HTML, trustedCmsContent); - Avoid
bypassSecurityTrust*methods unless absolutely necessary; when used, require code comments justifying the bypass and document the validation applied - Validate route parameters and query strings to prevent injection attacks
- Use Angular's built-in CSRF protection with HttpClient
- Validate and sanitize data before binding it in templates, especially when displaying user-generated content in
*ngForloops or other directives - Never use HTML comments (
<!-- -->) to store sensitive data or instructions in templates
Components (Essential)
- Use
OnPushchange detection strategy for performance - Inputs should be immutable (don't mutate input objects)
- Use
trackByfunction with*ngForfor lists - Prefer standalone components for new code (Angular 14+)
Templates (Essential)
- Avoid complex logic in templates (use getters or pipes)
- Use
ng-containerfor structural directives without extra DOM - Never use dynamic HTML with
[innerHTML]without proper sanitization; review all XSS risks
Services (Essential)
- Services should be
providedIn: 'root'unless scoped to feature - Use dependency injection, don't instantiate services manually
- HTTP calls belong in services, not components
RxJS (Essential)
- Always unsubscribe (use
takeUntilDestroyed(),asyncpipe, orDestroyRef) - Avoid nested subscribes (use
switchMap,mergeMap,concatMap) - Use
shareReplayfor HTTP calls that multiple subscribers need - Handle errors with
catchError(don't let errors kill the stream)
Module Organization
- Feature modules should be lazy-loaded where possible
- Use
SharedModulefor reusable components/pipes/directives. Explicitly define exports to make the module's public API clear - Use
CoreModulefor singleton services (provided in root); import only once in AppModule - Avoid circular module dependencies
Type Safety
- Enable strict TypeScript mode in tsconfig.json
- Use
strictTemplates: truein Angular compiler options - Avoid
anytype - use proper interfaces/types - Type all function parameters and return values
Accessibility
- Use semantic HTML elements (e.g.,
<button>not<div>with click) - Include ARIA labels and roles where needed
- Ensure keyboard navigation works for interactive elements
- Test with screen readers and accessibility tools
- Maintain proper heading hierarchy (h1, h2, h3)
- For advanced accessibility patterns, see Angular Accessibility Guide
Testing
- Use
@angular/testingutilities (TestBed, ComponentFixture) - Write unit tests for components, services, and pipes
- Mock dependencies in tests (don't use real HTTP calls)
- Test component inputs/outputs and DOM interactions
- Use
asyncandfakeAsyncfor testing asynchronous code
State Management (Advanced)
- Use NgRx or Akita for complex shared state
- Signals (Angular 16+) for reactive local state
- Services with BehaviorSubject for simple shared state
- Avoid component state for data shared across routes
Internationalization (Advanced)
- Use Angular i18n for localization
- Mark translatable text with
i18nattribute - Extract translations with
ng extract-i18n - Serve locale-specific builds or use runtime translation
- For detailed i18n patterns, see Angular i18n Guide
Linting and Code Style
- Use ESLint with @angular-eslint rules
- Follow Angular style guide conventions
- Use Prettier for consistent code formatting
- Enable editor support for automatic linting/formatting