Angular Standalone components

by Leonie — 7 minutes

Angular recently announced one of the greatest new features since the introduction of Ivy: standalone components. What does this concept entail and what impact will it have on developing in Angular?

Standalone components: what does it mean?

As the name suggests, the introduction of standalone components makes it possible to create a component without the need to declare and export it through a module. Such a component can be directly imported by other components or modules, while it imports its own dependencies. The concept applies to directives and pipes as well.

The introduction of standalone components doesn't mean the end of the Angular module (ngModule). The concept is also coined as "optional modules", from which we can take that modules can still be used. A standalone component can import a module and vice versa. In other words: ngModules and standalone components can live together in one codebase.

What does a standalone component look like?

For a component to be considered by Angular as standalone, it requires the new property "standalone" in the component decorator to be set to "true". For a component to import its own dependencies, the component decorator has been extended with properties similar to those already existing for the ngModule: imports, providers and schemes.

As the standalone has its own dependencies, it also needs to import other components, if the template requires their use.

In the following code snippet a standalone component is declared, which in its turn imports some modules and another standalone component:

  import { CommonModule } from '@angular/common';
  import { Component } from '@angular/core';
  import { ChildStandaloneComponent } from './child-standalone.component';


  @Component({
    selector: 'sa-component',
    standalone: true,
    imports: [
        CommonModule,
        AnotherStandaloneComponent
    ],
    exports: [StandaloneComponent]
    template:
    `<div *ngIf="foo">
      <sa-another-standalone></sa-another-standalone>
    </div>`
  })
  export class StandAloneComponent  {
    foo = true;
  }

The example above shows a small component, with a dependency in its template on another component and a condition. To make this work, we need to import this other component and we need to import Angulars' CommonModule. The component also exports itself, to make it available to other standalone components or modules.

What about bootstrapping and routing?

If you've ever worked with Angular, you will know that modules are not just declared to bundle components. Bootstrapping and routing are also done through modules. Will you still need those if you decide on a standalone component-architecture?

Although a proposal has already been made to bootstrap Angular through a component, we cannot expect this feature to be present at the first introduction of standalone components.

It is however currently possible to lazy-load a module/component from a component. So in the future it will be possible to set up an Angular application without a single module.

What benefits do standalone components bring?

The main benefit of using standalone components, according to the Angular-team, is that it will make the learning curve of Angular less steep. For a beginning Angular-developer, the framework may appear somewhat intimidating, mostly due to the way modules are used.

Learning Angular using standalone components should make it easier to understand the concepts behind the framework, while the development work should become less cumbersome. After all, with standalone components:

  • it is easier to understand which dependencies a component relies on
  • importing components and directives will be easier as you don't need to import the entire module
  • there are no implicit dependencies
  • less files means there is less boilerplate to write

In short, the whole "mental model" of Angular will be more simple and easier to reason about. The benefits for beginning Angular-developers are clearly there, while for the more experienced developers there is no urgent need to learn new techniques, as ngModules will still exist. Anyway, the concept of standalone components should have no surprises to an experienced Angular developer.

The Angular-team made it clear that the new concept should not have any negative impact on performance and build-time. In fact, standalone components are expected to shorten the build-time somewhat, so in this respect we can also expect benefits.

All good news so far, are there any cons?

The benefits as described by the Angular-team, are all fair and well. Angular is certainly not the most intuitive framework to learn, as I have experienced myself and its module system is definitely one of the reasons why. Nevertheless I do have some concerns when taking existing projects into consideration:

In an enterprise-size project, migrating to standalone components will be a large undertaking, so one would either have to decide not to allow developers to use this new concept, or allow both to live together. In case a team or organisation chooses to allow both, it will mean a beginning Angular-developer would still have to grasp the concept of ngModules and how they differ from standalone components. In fact, it may just make it harder to understand the codebase.

Migrating code to standalone components will be relatively easy for projects where the SCAM-principle is applied. The SCAM-principle, in highly simplified words, prescribes the creation of a module for each and every component, directive or pipe so they can all be exported on their own. (See https://dev.to/this-is-angular/emulating-tree-shakable-components-using-single-component-angular-modules-13do ). As each component is already coupled to just one module, it will be easier to convert it to a standalone version.

But migrating all code to standalone components might not always be what you want. Bundling components in a module and exporting only some, is in itself a perfectly fine pattern. How would you translate this to standalone components? Instead of an ngModule, you will have to set up an api using barrelfiles, while protecting the private components with linting rules. In this respect, standalone components do not necessarily make a project easier to manage.

The argument that standalone components remove a lot of boilerplate is only partially true. Creating a module is no longer necessary, but instead pretty much every component will need to import at least CommomModule for Angular to work as expected. There is no easy answer to this issue. Suggestions have been made to cut up the CommonModule so you only have to import what is needed, but this could easily lead to a long list of imports. An alternative could be that certain features, such as the *ngIf directive, are imported by default. Currently there are no concrete plans by the Angular-team in this direction.

So, are standalone components a good development?

Standalone components certainly have their benefit for anyone picking up the Angular-framework. Considering the projects that I've worked on myself, I clearly see the benefit when it comes to small units such as directives and pipes. It will definitely make life easier if you can just import one single directive or pipe. Also shared, representational components will be easier to share when they are standalone. When developing more complex features, I'm not so sure whether standalone components will be my first choice.

When can we expect standalone components to become available?

The expectation is that Angular 14 will introduce standalone components. As Angular has a major release every six months and the last release was in November 2021, this could be any moment.

Conclusion

With standalone components, the Angular-team will introduce a new way of working that will make the learning curve for beginning Angular-developers less steep. This introduction will not be breaking in any respect, co-existing peacefully with the existing module system. The benefits offered by standalone components will be mostly felt in clearly defined, smaller pieces of code like pipes. Migrating an existing codebase to standalone components, if wanted at all, may be a challenge.

meerdivotion

Cases

Blogs

Event