💯 Best Practices for Angular Directives

Angular 20, the latest release in Google’s powerful frontend framework, continues to empower developers with tools for building dynamic, scalable, and maintainable web applications. One of its most versatile features is directives — a way to extend HTML with custom behavior.

Whether you’re creating structural directives like *ngIf or attribute directives to change styles or behavior, following best practices ensures your code remains clean, efficient, and reusable. In this post, we’ll cover the best practices for Angular directives in version 20.

📌 1. Understand When to Use Directives

Before diving into best practices, clarify whether a directive is the right tool:

  • Use a component when your functionality has a view/template.
  • Use a directive when you’re extending behavior without a template, especially for DOM manipulation or structural transformations.

🛠️ 2. Choose the Right Type: Structural vs Attribute

Angular supports two directive types:

Directive TypeExampleUse Case
Structural*ngIf, *ngForAdd or remove elements in the DOM
AttributengClass, ngStyleChange appearance or behavior of existing DOM elements

🧼 3. Keep It Single-Responsibility

Each directive should have one focused purpose. Trying to pack too much logic into a directive will lead to complexity and harder testing.

Good Example: A directive that changes the background color on hover.

Bad Example: A directive that changes style, listens to keyboard events, and fetches data.

🔁 4. Use @Input() and @Output() Properly

Directives should be configurable and reusable:

@Directive({
  selector: '[appHighlight]',
  standalone: true
})
export class HighlightDirective {
  @Input() appHighlight = 'yellow';

  constructor(private el: ElementRef) {}

  ngOnInit() {
    this.el.nativeElement.style.backgroundColor = this.appHighlight;
  }
}

This allows the directive to adapt its behavior based on the input value:

<p [appHighlight]="'lightblue'">Highlighted Text</p>

⚙️ 5. Inject Services, Not Logic

Angular directives can inject services. Offload reusable business logic into injectable services rather than cramming everything into the directive itself.

This improves testability, reusability, and separation of concerns.

🔍 6. Be Cautious with ElementRef and Renderer2

Direct DOM access via ElementRef.nativeElement can lead to security issues and cross-platform incompatibility.

✅ Always prefer Renderer2 for DOM manipulations:

constructor(private renderer: Renderer2, private el: ElementRef) {}

ngOnInit() {
  this.renderer.setStyle(this.el.nativeElement, 'color', 'blue');
}

📦 7. Make It Standalone

Angular 20 emphasizes standalone APIs to simplify app architecture and module management. Use the standalone: true option to make your directives modular and easily sharable across features.

@Directive({
  selector: '[appAutofocus]',
  standalone: true
})
export class AutofocusDirective implements AfterViewInit {
  constructor(private el: ElementRef) {}

  ngAfterViewInit() {
    this.el.nativeElement.focus();
  }
}

🧪 8. Write Unit Tests for Directives

Like any Angular building block, directives deserve unit tests. Angular’s TestBed allows isolated testing of directives using host components:

@Component({
  template: `<input appAutofocus />`
})
class TestHostComponent {}

it('should autofocus the input', () => {
  const fixture = TestBed.createComponent(TestHostComponent);
  fixture.detectChanges();
  const input = fixture.nativeElement.querySelector('input');
  expect(document.activeElement).toBe(input);
});

⚠️ 9. Avoid Overusing Directives

Just because you can make something a directive doesn’t mean you should. Overuse can lead to:

  • Confusing HTML templates
  • Difficult debugging
  • Reduced performance

Use components for anything with significant UI or interactions.

📁 10. Organize and Document

Group related directives together, document their usage, and provide examples in your codebase. This helps new developers onboard faster and reduces misuse.

Use meaningful selectors: appDraggable, appAutoResize, appPermissionOnly, etc.

✨ Conclusion

Angular directives are a powerful tool — when used wisely. Angular v20’s modern features, like standalone APIs and enhanced typing, make it easier than ever to build clean, maintainable directives.

Stick to the principles of single responsibility, safe DOM interaction, testability, and reusability, and your directives will become a powerful part of your UI toolkit. Happy Coding!

Leave a comment