A new Angular app does not need AppModule. bootstrapApplication starts one component and a list of providers. NgModules still run. They are not the default shape to copy into a new feature.
Hub: Architecture. Pair this with Angular and .NET integration. Interview prompts that mention this in passing live on Angular interview questions. Do not treat that list as this guide.
Real-world analogy
An NgModule is a department that must sign every new hire before they can sit down. A standalone component is a person with their own badge who declares the tools they use. The building (the API, the router, HTTP) is still shared. You stop making every hire walk through one department desk.
Worked example
A feature module imports HttpClientModule, RouterModule.forChild, and a shared CoreModule that also imports HttpClientModule. One interceptor refreshes the token. After a lazy load, a 401 fires the refresh twice because HTTP was registered twice. The standalone version deletes the feature module. The route uses loadComponent. main.ts calls provideHttpClient once, with the interceptor. The second refresh disappears because there is one client.
| Old wiring | Standalone wiring |
|---|---|
platformBrowserDynamic().bootstrapModule(AppModule) | bootstrapApplication(AppComponent, { providers }) |
RouterModule.forRoot | provideRouter(routes) |
HttpClientModule | provideHttpClient(...) |
loadChildren: () => import(...).then(m => m.FeatureModule) | loadComponent: () => import(...).then(m => m.Page) |
Code
bootstrapApplication(AppComponent, {
providers: [
provideRouter(routes),
provideHttpClient(withInterceptors([authInterceptor])),
],
});
Leave an existing NgModule in place until you are in that folder for a real change. A weekend rewrite of every module does not change what the API returns. Screen state after this wiring is the signals post, not a second copy of it.
The shop screens that load this way sit in Ecom_NET10.