When building small Angular apps, everything feels simple. But as your application grows—more features, more developers, more screens—your code structure either becomes organized… or chaos.
This article will help you avoid chaos.
We will cover:
What Angular Modules are (and why they matter)
Types of Angular Modules
Lazy Loading (with real examples)
Folder structure best practices used in real enterprise applications
1️⃣ What Are Angular Modules?
An Angular Module (NgModule) is a container that groups related components, directives, pipes, and services. It acts like a “room” in a house — every feature gets its own space.
A basic module looks like:
@NgModule({
declarations: [HomeComponent],
imports: [CommonModule],
exports: [HomeComponent]
})
export class HomeModule { }
Why do modules exist?
| Purpose | Meaning |
|---|
| Organization | Keep related files together (like features) |
| Reusability | Share components across modules |
| Performance | Enable Lazy Loading |
| Scalability | Manage a growing enterprise app |
2️⃣ Types of Angular Modules
Not all modules serve the same purpose. Below are the common categories used by professionals:
| Module Type | Purpose | Example |
|---|
| Root Module | App entry point | AppModule |
| Feature Module | One feature, one module | UsersModule, OrdersModule |
| Shared Module | Components used across features | Buttons, Tables, Pipes |
| Core Module | Singleton services (auth, API) | AuthService, HttpInterceptor |
Example Folder with Modules
src/app/
├── app.module.ts
├── core/
│ └── core.module.ts
├── shared/
│ └── shared.module.ts
├── features/
│ ├── users/
│ │ ├── users.module.ts
│ ├── orders/
│ │ ├── orders.module.ts
3️⃣ Lazy Loading — The Game Changer
Lazy loading means loading modules only when needed, instead of loading everything at startup.
👉 Result? Faster performance and better UX.
Without Lazy Loading (Bad for large apps)
@NgModule({
imports: [
BrowserModule,
UsersModule,
OrdersModule
]
})
export class AppModule {}
Everything loads upfront — even if the user never visits /users.
With Lazy Loading (Better Approach)
In app-routing.module.ts:
const routes: Routes = [
{
path: 'users',
loadChildren: () =>
import('./features/users/users.module').then(m => m.UsersModule)
}
];
Angular will now load the UsersModule ONLY when the user opens /users.
Example of Feature Module Routing
users-routing.module.ts:
const routes: Routes = [
{ path: '', component: UsersListComponent },
{ path: 'add', component: AddUserComponent }
];
When Should You Use Lazy Loading?
| Scenario | Should Lazy Load? |
|---|
| Feature with multiple components & separate screens (large) | ✅ YES |
| Shared utilities or common UI | ❌ NO |
| Admin sections not accessed regularly | ✅ YES |
| Small feature with 1 component | ❌ Optional |
4️⃣ Folder Structure Best Practices
The best structure depends on project size. Here's a scalable and enterprise-friendly example:
src/app/
├── core/
│ ├── guards/
│ ├── interceptors/
│ ├── services/
│ └── core.module.ts
├── shared/
│ ├── components/
│ ├── pipes/
│ ├── directives/
│ └── shared.module.ts
├── features/
│ ├── auth/
│ │ ├── login/
│ │ ├── register/
│ │ └── auth.module.ts
│ ├── dashboard/
│ │ └── dashboard.module.ts
├── app-routing.module.ts
└── app.module.ts
Why this structure works?
Clear separation of responsibilities
Easy navigation for developers
Supports lazy loading and reusability
Scales with project size
5️⃣ Common Mistakes to Avoid
| Mistake | Fix |
|---|
Putting everything in AppModule | Create modules per feature |
Importing SharedModule everywhere | Only import where needed |
| Storing services in feature modules incorrectly | Move singleton services to CoreModule |
| Not wildcard lazy-loaded modules | Verify routing structure |
Quick Recap
✔ Angular modules organize and scale your application
✔ Feature modules help structure major functionalities
✔ Lazy loading improves performance
✔ A clean folder structure makes your code maintainable
Final Thought
Treat your Angular application like a city.
Modules are districts. Lazy loading is the highway system deciding which district opens when needed.