Skip to main content

Angular Style Guide

This guide covers a range of style conventions for Angular application code. These recommendations are not required for Angular to work, but instead establish a set of coding practices that promote consistency across the Angular ecosystem.

Naming Conventions

File Naming

Use Hyphens

Separate words within a file name with hyphens (-). For example, a component named UserProfile has a file name user-profile.ts.

Match Identifiers

File names should generally describe the contents of the code in the file. When the file contains a TypeScript class, the file name should reflect that class name.

Component Files Structure

Components typically consist of one TypeScript file, one template file, and one style file. These files should share the same name with different file extensions:
For unit tests, end file names with .spec.ts. For example, the unit test file for the UserProfile component has the file name user-profile.spec.ts.

Project Structure

Source Directory Organization

All of your Angular UI code (TypeScript, HTML, and styles) should live inside a directory named src. Code that’s not related to UI, such as configuration files or scripts, should live outside the src directory.

Feature-Based Organization

Organize your project into subdirectories based on the features of your application or common themes to the code in those directories:
Avoid creating subdirectories based on the type of code that lives in those directories. For example, avoid creating directories like components, directives, and services.

Bootstrap in main.ts

The code to start up, or bootstrap, an Angular application should always live in a file named main.ts. This represents the primary entry point to the application.
main.ts

Dependency Injection

Prefer inject() Function

Prefer using the inject() function over injecting constructor parameters. The inject() function offers several style advantages:

Better Readability

More readable, especially when a class injects many dependencies

Better Type Inference

Offers better type inference and easier to add comments

Components and Directives

Component Selectors

Always use an application-specific prefix for component selectors to avoid naming conflicts with third-party components:

Member Access Modifiers

Use protected on class members that are only used by a component’s template:

Use readonly for Angular Properties

Mark component and directive properties initialized by Angular as readonly. This includes properties initialized by input, model, output, and queries:

Organize Class Members

Group Angular-specific properties together, typically near the top of the class declaration:

Template Best Practices

Prefer class and style Bindings

Prefer class and style bindings over using the NgClass and NgStyle directives:
Both class and style bindings use a more straightforward syntax that aligns closely with standard HTML attributes. Additionally, they incur less performance overhead compared to the NgClass and NgStyle directives.

Name Event Handlers Meaningfully

Prefer naming event handlers for the action they perform rather than for the triggering event:

Keep Lifecycle Methods Simple

Avoid putting long or complex logic inside lifecycle hooks. Instead, create well-named methods to contain that logic:

Avoid Complex Template Logic

When the code in a template gets too complex, refactor logic into the TypeScript code, typically with a computed signal:

TypeScript Best Practices

Use Lifecycle Hook Interfaces

When adding a lifecycle hook to your class, import and implement these interfaces to ensure that the methods are named correctly:

Prefer const over let

Use const wherever possible, only using let when a value must change. Avoid var unless absolutely necessary:

Avoid any Type

Avoid any where possible. Consider whether a generic or unknown may be appropriate:

Summary

  • Use hyphen-case for file names (e.g., user-profile.component.ts)
  • Use application-specific prefixes for selectors (e.g., app-user-profile)
  • Use PascalCase for class names
  • Use camelCase for functions and methods
  • Use UPPER_SNAKE_CASE for constants
  • Organize by feature, not by type
  • Keep related files together in the same directory
  • Bootstrap in main.ts directly inside src
  • One concept per file
  • Use inject() function over constructor injection
  • Use protected for template-only members
  • Use readonly for Angular-initialized properties
  • Group Angular properties before methods
  • Keep lifecycle methods simple
  • Prefer class and style bindings over NgClass/NgStyle
  • Name event handlers for what they do
  • Avoid complex template logic
  • Refactor complex expressions to computed signals

Next Steps

Learn about performance optimization techniques in Angular