Angular Standalone Components: Welcome to a World Without NgModule

Netanel Basal
Netanel Basal
Published in
2 min readMay 12, 2022

--

The powers that be have spoken, and based on the community’s feedback, the often maligned NgModule is on its way out (partially). Angular 14 introduces an alternative way to write applications — Standalone components, directives, and pipes.

The term “standalone” refers to components, directives, or pipes that can be used independently of NgModule. Although you’ll still need to use the core and external NgModules, you probably won’t need to create new ones.

Let’s create an application without NgModules. First, we need to generate it using the angular-cli:

npm init @angular ng14

The next step is to delete app.module.ts and replace the bootstrapModule() function in main.ts with bootstrapApplication():

The bootstrapApplication() can take a list of providers that should be available to the root component and all its children:

As the name suggests, the function extracts the providers from the provided module.

Now we need to change the AppComponent to be a standalone component. Simply set the standalone property to true:

You should see the AppComponent’s template in your browser. As our component is standalone, we can use the new imports property. The imports property specifies the template dependencies of the component — those directives, components, and pipes it can use.

Standalone components can import other standalone components, directives, pipes, and existing NgModules. For example, we can create a standalone directive, and use it in our component:

npx ng g directive foo --standalone

That’s neat. Now, let’s add routing to the application. You might be tempted to add it to the AppComponent:

Unfortunately, that isn’t possible because Angular doesn’t allow you to use ModuleWithProvider in a standalone component. Next, we might try using the new importProvidersFrom function in the component’s providers:

Using in-app navigation will work; however, the router will miss the first navigation. Initialization of the router should be performed in the bootstrap process:

Now it works as expected. The TodosPageComponent is eagerly loaded. Let’s change it to load lazily and add a TodoPageComponent:

Instead of using loadChildren and passing a NgModule, we use the loadComponent property and pass a component. We can also declare providers for this Route and its children using the new providers property:

We can also pass an array of routes to loadChildren:

There will be more to come, so stay tuned 😋

Follow me on Medium or Twitter to read more about Angular and JS!

--

--

A FrontEnd Tech Lead, blogger, and open source maintainer. The founder of ngneat, husband and father.