tldr;
For years, Angular has been organized and built on top of modules. These modules grouped functionality inside your app. Components, pipes, services, and directives that had related purpose were grouped together and declared inside modules, which would need to be imported in another part of the app to be used. This pattern works, and the organization for your component is nice, but it does complicate learning Angular for the first time. To get started with an app, a beginner has to learn what a component is and what a module is and how they work together. This makes it more complicated to jump in and get started. Standalone components coming to Angular is a big step towards simplifying different parts of your app, and simplifying the learning process.
Throughout this article I’ll use the term “standalone components”, but these same methods can be used with pipes, directives, guards, and other pieces of an Angular application that you would normally have to declare inside an NgModule.
What are Standalone Components?
A typical Angular component is created and added to the declarations array of an NgModule. If the component is not added to the declarations array, it cannot be used by any other components, whether inside that same module or another one (by importing the module in a separate one). Thus, we can see that components have been, up until now, tied to modules.
Standalone components are named this way because they “stand alone” from NgModules. They do not need to be included in the declarations array to be used in other places. Instead, the component itself is imported where it needs to be used. Now, components can be be created and used without an NgModule. You could, theoretically, build an entire application without a custom NgModule.
Example Standalone Component
Now that we know what standalone components are, let’s look at an example of one.
import { CommonModule } from ‘@angular/common’;
import { Component, Input } from ‘@angular/core’;@Component({
selector: ‘app-name’,
standalone: true,
imports: [CommonModule],
template: `<h1>{{ name | titlecase }}</h1>`,
styles: [
`
h1 {
color: blue;
}
`,
],
})
export class NameComponent {
@Input() name: string | undefined;
}
This component takes a name as an input and then outputs it on the page while title casing the string. For the most part, it looks just like any other component you’ve created in an Angular application. There are just a couple differences. First, we need to designate the component as standalone, which is done in the @Component decorator’s metadata with the standalone: true key/value pair. The other part that looks different from past components you’ve created is that there is an imports attribute in the metadata, where you can import NgModules and/or other standalone components to be used inside this component. In the above example, the CommonModule is imported so the titlecase pipe can be used.
To use this standalone component somewhere else, it needs to be imported. It can be imported in an NgModule or in another standalone component:
import { NameComponent } from ‘./app/name.component’;@Component({
selector: ‘app-root’,
standalone: true,
imports: [
NameComponent,
CommonModule,
],
template: `
<app-name *ngIf=”name” [name]=”name”></app-name>
`,
})
export class AppRootStandaloneComponent {
name = ‘preston lamb’;
}
Bootstrapping an Application from a Standalone Component
In addition to creating normal standalone components that are used throughout the app, you can create a standalone component that is used to bootstrap the application. In the past, bootstrapping an application has been done by a module. That still works, and you can continue to use that method if you’d like. However, you can now use a standalone component as the root of the application. Let’s say we want to use the above AppRootStandaloneComponent as our root component for our app, and want to start the app with that component. We could bootstrap the app with the following code:
import { bootstrapApplication } from ‘@angular/platform-browser’;bootstrapApplication(ExampleStandaloneComponent)
.then((ref) => {
// do some stuff
})
.catch((err) => console.error(err));
This is similar to bootstrapping an application with a module, but it is slightly different. Both ways work and you can choose the way that you prefer.
What’s Next?
Standalone components are currently in developer preview only in Angular v14. You can try them out now, but they are not quite ready for prime time. In the coming months, we will see these become stable and be more frequently used in Angular applications.
Until then, it’ll be helpful to play with standalone components and understand what they are and how they’re used. If you’re a library developer, this may be especially helpful for you as you plan to upgrade your library.
Angular Standalone Components was originally published in ngconf on Medium, where people are continuing the conversation by highlighting and responding to this story.