Log in to like this post! A Comprehensive Guide to Angular Standalone Components Desislava Dincheva / Thursday, July 6, 2023 If there’s one framework that leaves no stone unturned when it comes to changing and enhancing the development process, it’s Angular. With the latest Angular 16.0.0 release, there are now some major advancements in things like tooling, server-side rendering, and reactivity. And to me, the introduction of Angular standalone API is one of the biggest improvements in the latest version that brings tons of advantages to the dev community. The new feature called Schematics for Standalone Components, in particular, seems to be revamping our ability to build reusable UI elements and libraries while eliminating boilerplate modules at the same time. And isn’t that changing the game significantly? But let’s take a deep dive into Standalone Angular Components (SACs) to better understand all the excitement around them as well as how exactly they work, how to create them, what has changed since Angular 14 when the concept for standalone components was first presented, and so forth. Highlights and key questions that the article discusses: What is a standalone component in Angular Angular standalone component benefits How to create a standalone component in Angular Standalone components with Ignite UI for Angular The best practices for Angular standalone components What Is a Standalone Component in Angular or Is This a Goodbye to NgModules? The shortest way to define them is that standalone components allow us to build Angular applications without using Modules. Since they are not tied to any specific module, they can be used in any part of the application. This means that standalone classes don’t need to be declared in an NgModule, so we have less boilerplate code. Basically, standalone components are not mandatory. Recommended yes, but not mandatory. However, Angular recommends always using Standalone components, at least for new components you create. They are simply more treeshakeable and less boiler. You can mix standalone components and modules. I agree that we can use standalone components over modules, at least going forward, but if you decide to leave the rest of your component modularized, that's not a bad decision. In Angular 14, the idea of standalone components was introduced along with standalone APIs – a developer preview at that time. They referred to a type of component which wasn’t part of any module and could be used independently without being nested within other components. In contrast, when you wanted to make a component before that, you'd typically have to pass it inside the declaration array of the module. Then, the concept started to change, and the development process gradually evolved. The official Angular documentation, for instance, stipulates that “standalone components, directives, and pipes aim to streamline the authoring experience by reducing the need for NgModule. Existing applications can optionally and incrementally adopt the new standalone style without any breaking changes.” In other words, we have simplification here. Now with Angular 16, we officially get the Schematics for Standalone Components feature and standalone components that are designed to be self-contained, modular, and reusable. But why use standalone components in Angular? While they’re not completely replacing the use of NgModules, they enable us to utilize a new way of creating modular and reusable code. Along the way, we even achieve better maintainability and testability for our Angular apps, plus a project structure that remains intact. This is such a great alternative! But again, standalone components in Angular are not a replacement but an alternative to NgModules. What Other Angular Standalone Component Benefits Are There? Here are a few more reasons to use standalone components in Angular: They are the lightweight solution that can effectively eliminate the class and every other excess that comes with it. Ability to adopt a more functional API compared to the much heavier class-based API it used to have. We can now lazy-load the component directly without an NgModule. They come with the ability to encapsulate functionality and promote code reusability throughout the app without causing potential bugs with other components. There’s no need for an AppModule any longer as we can bootstrap the application with a component. Routing in standalone Angular components is now more tree-shakable so we can directly point to a routed component or route configuration. They can easily import other standalone components, directives, pipes, and existing NgModules too. Each component has its own file (template, styles, TypeScript code), resulting in a much better code structure. You design components with reusability in mind and can easily add new features or extend existing functionalities. You can write unit tests specifically for each Angular standalone component. How To Create A Standalone Component in Angular? Creating them Creating your first standalone component is super easy and it happens by using the –-standalone flag. But first, make sure you’re on Angular 16. 2. Using them You can use a standalone component in two ways: In another standalone component by simply passing it to the imports property of the same standalone component. Or inside a Module by passing it to the imports array. Using Standalone Components with Ignite UI for Angular Starting with Angular 16 and Ignite UI for Angular 16.0 you can now simply add the imports that your standalone component needs in the imports property. In the following example IGX_GRID_DIRECTIVES can be used to import all grid-related components and directives. Here's how to create and use a standalone component in Angular with Ignite UI. import {IGX_GRID_DIRECTIVES} from 'igniteui-angular'; @Component({ selector: 'app-grid-sample', styleUrls: ['grid.sample.scss'], templateUrl: 'grid.sample.html', standalone: true, imports: [IGX_GRID_DIRECTIVES, AsyncPipe] }) You can also import all components used by your standalone component individually. An example with the IgxGridComponent and IgxColumnComponent, when only these two are used by another component, is as follows. import {IgxGridComponent, IgxColumnComponent} from 'igniteui-angular'; @Component({ selector: 'app-grid-sample', styleUrls: ['grid.sample.scss'], templateUrl: 'grid.sample.html', standalone: true, imports: [IgxGridComponent, IgxColumnComponent, AsyncPipe] }) All Ignite UI for Angular components are now exported as standalone components. The library still exports NgModules, which have been preserved for backward compatibility, but they no longer declare any of the Ignite UI for Angular components. Instead, they just import and export the standalone components. It’s important to note that the standalone components are still in a preview stage. Some utility directive exports may change in the future and may be missing from the documentation in the initial release, hence the preview state of the feature. What Are Some of the Best Practices for Angular Standalone Components? When working with Angular standalone components, you can follow several best practices to ensure clean, maintainable, and reusable code, as well as next-level projects. Consider The Size Of Your Project & Code As a first step, consider your project's size and how your code is organized. You may read that there are no breaking changes related to the migration from regular to standalone components if you just switch all of your components to standalone. However, I can guarantee you that you will introduce some major bugs into your application. But you might not want to migrate all of your code to standalone components. Bundling components in a module and exporting only some of them is 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 case, standalone components do not necessarily make a project easier to manage. So, if the size of your project is medium to large, my advice is to start this migration rather slowly and just migrate all of the SCAM (Single Component Angular Module). With SCAM, an NgModule declares only one component. Because they are already separate, you can get used to how to create and work with standalone components from then on. Migrate Pipes & Directives Another good practice is to migrate all of your pipes and directives to standalone components. This way, you can simplify and reduce some of the modules. Adjust & Continuously Improve the Code After that, give yourself and your team time to adjust and continuously improve your code base during some regular code refactoring. Because in an enterprise-size project, migrating to standalone components will be a large undertaking. By doing this, you can ensure that no regressions are introduced whereas all changes are well-tested and reviewed by your colleagues. In Conclusion... The argument that standalone components remove a lot of boilerplate for me is only partially true. Creating a module is no longer necessary. Instead, almost all components will need to import at least CommomModule for Angular to work as expected. For more complex cases, a pretty long list of other modules and components will also have to be imported. In some cases, then, this leads to really long import statements and when you open a file, you must scroll an entire page to actually see the code of the component itself. 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, there is nothing wrong with allowing both concepts to live together in your project’s code base for some time and seeing how your project will continue to evolve and what exactly will work best.