Angular Naming Style Guide
A guide to naming Angular components, services, pipes, directives, and more.
The updated official Angular style guide introduces a new naming rule, encouraging not to use suffixes anymore for Components, Directives, and Services.
Rather than using HomeComponent
, HighlightDirective
, and UserService
, you should use Home
, Highlight
, and UserApi
.
There are two motivations behind this rule:
- To avoid relying too much on sufffixes too be lazy about proper naming.
- To prepare Angular future with the arrival of selectorless components, where we’ll be able to use the component class name directly in a template (ie
<app-home />
-><Home />
).
Introduced with Angular v20 release, the new style guide not just encourage but enforce this new naming convention by updating the documentation and removing the suffixes for new v20 projects.
However, We still miss guidelines to help us migrate to this new naming convention. Here is an attempt to help you!
The conflict dilemma
Given you have to deal with users in your application, it’s quite common to have:
- a interface/type named
User
- a service named
UserService
- a component named
UserComponent
The question is: what happens by removing the suffixes?
UserService
->User
UserComponent
->User
User
->User
Everything is called User
now.
Types
This content should not change: name type for exactly what they are: a User
, a Flower
, etc.
Do not prefix them with I
(such as IUser
) or suffix them with Model
(such as UserModel
).
Services
Services have (or should have) a single responsibility and that’s already the case in most projects. A service is mainly used for 2 motivations:
- to share data between different parts of the application (when not provided to an isolated element)
- to isolate some logic which require dependancy injection, such as HttpClient.
Service as an API layer
Even if we could use the HttpClient
service directly in the component, isolating the logic in a service has always been a good practice.
Such a good practice is not limited to HttpClient
though, it could be used for any logic that requires dependancy injection to expose a third party API to the application, like a Firebase
service or a graphql client.
There are multiple ways to name such a service:
UserApi
UserClient
UserGateway
UserApiService
UserApiClient
UserDataClient
Select the one that best fits your mindset but stick to it for consistency.
ng generate service user/user-api
@Injectable({
providedIn: 'root',
})
export class UserApi {
private readonly http = inject(HttpClient);
getUser(id: string): User {
return this.http.get<User>(`/api/users/${id}`);
}
}
#### Service as a state provider
We commonly called 'stores' the elements reponsible to provide a state to the application.
So you can suffix your service with `Store` to indicate that it's a state provider:
```bash
ng generate service user/user-store
@Injectable({
providedIn: "root",
})
export class UserStore {
private readonly _user = signal<User | null>(null);
public readonly user = this._user.asReadonly();
}
Some stores are not reated ot the whole application, but to a specific part of the application, even something only provided to a component.
Besides the Store
suffix, you should care about its exact context and name it accordingly. If tied to the UserPage, you can name it UserPageStore
.
- The
UserStore
is a global store, so it’s not tied to a specific component. - The
UserPageStore
is a store tied to theUserPage
component.
Components
We usually called them quite lazily, like UserComponent
, HomeComponent
, etc.
Removing the suffixes might be an issue as creating naming conflicts, such as UserComponent
now called User
in the same way as the model.
Semantic naming
The best way to name a component is to use a semantic name that describes what it does.
Pages
Page
is a common term used to describe a routed component taking most of the document space (most of the time minus the header and footer).
It’s also a term used by the Atomic Design methodology, as wrapping multiple related elements.
ng generate component user/user-page
@Component({
selector: "app-user-page",
templateUrl: "./user-page.html",
styleUrls: ["./user-page.scss"],
})
export class UserPage {}
Suffixing the feature name with Page
is a good way to indicate that it’s a page but it might be specific enough: for a given feature, your application might have multiple pages.
It can be a page about:
- a user profile:
UserProfilePage
- a user form:
UserFormPage
- a user list:
UserListPage
- a user details:
UserDetailsPage
Non routed components
Non routed components are components that are not tied to a specific route. They are usually used to display a list of items, a form, a details, etc. That’s the most important part of the application.
This guide will focus on some common patterns you can use to name your components.
Display an array of items
It’s quite common to display a array of items in a component. Another common way to explain it is to call about a list
of items.
But let’s divide this into two patterns:
- a simple list (like the Angular Material list)
- a table (like the Angular Material table)
ng generate component user/user-list
ng generate component user/user-table
If you happen to have dedicated filters or pagination, you can isolate their logic in a dedicated component, using UserList
or UserTable
as a base to identify their specfic usage:
ng generate component user/user-list-filters
ng generate component user/user-list-pagination
ng generate component user/user-table-filters
ng generate component user/user-table-pagination
If filters and/or pagination are isolated in dedicated components this way rather than being part of List
/Page
, you can wrap the UserList
and the UserListFilters
components in a UserExplorer
component.
Display a form
You could just suffix the form component with Form
such as UserForm
. But how they behave depends on the usage: some are meant to be used for creation, some for edition, some for both.
Use these patterns to name your form components:
UserCreateForm
UserEditForm
UserForm
(when meant to be used for both creation and edition)