Skip to content

Angular Feature Modules

As an Angular application grows, organizing code by feature (domain), rather than by file type, keeps it navigable. This lesson covers the feature module pattern and its standalone-friendly folder structure equivalent.

What Is a Feature Module (or Feature Folder)?

A feature module groups everything related to one part of the application's domain, orders, settings, user profile, into its own cohesive unit: components, services, routes, and (in classic Angular) its own NgModule.

With standalone components, the same organizational idea continues as a folder structure convention rather than a formal module class, each feature still gets its own folder with its own routes, components, and services.

src/app/
  core/            <- app-wide singletons, guards, interceptors
  shared/ui/       <- reusable, presentation-only building blocks
  features/
    orders/
      orders.routes.ts
      order-list.component.ts
      order-detail.component.ts
      order.service.ts
    settings/
      settings.routes.ts
      settings.component.ts

Each feature folder is self-contained: everything related to "orders" lives together, rather than scattered across generic components/, services/ folders.

A Feature's Own Route File

// orders.routes.ts
export const ORDERS_ROUTES: Routes = [
  { path: '', component: OrderListComponent },
  { path: ':id', component: OrderDetailComponent },
];

// app.routes.ts
{ path: 'orders', loadChildren: () => import('./features/orders/orders.routes').then(m => m.ORDERS_ROUTES) }
  • Each feature typically exposes its own Routes array, lazily loaded from the app's root routes.
  • Feature-specific services are scoped (via providedIn: 'root' or route-level providers) based on how widely they need to be shared.
  • Feature folders keep related files together instead of splitting by file type across the whole app.
  • A core/ folder is a common convention for genuinely app-wide singletons (auth, logging, guards).

Feature Organization Cheatsheet

Common top-level folder conventions in a feature-organized Angular app.

Folder Contains
core/ App-wide singleton services, guards, interceptors
shared/ui/ Reusable, presentation-only components/directives/pipes
features/<name>/ Everything specific to one feature/domain
features/<name>/<name>.routes.ts That feature's own route configuration
features/<name>/<name>.service.ts Data access/business logic specific to that feature

Why Organize by Feature Instead of File Type

Organizing by file type (a top-level components/, services/, pipes/ folder for the whole app) scales poorly, related files end up far apart, and finding "everything about orders" means searching across many unrelated folders. Organizing by feature keeps related code physically close together.

  • Related files (order-list.component.ts, order.service.ts) live next to each other.
  • New team members can understand one feature folder without needing to understand the whole app first.
  • Feature folders map naturally onto lazy-loaded route boundaries.

A Classic Feature Module (Legacy Reference)

In NgModule-based Angular, the same organizational goal was expressed as a dedicated feature module, often lazily loaded via loadChildren pointing at the module itself rather than a bare routes file.

@NgModule({
  declarations: [OrderListComponent, OrderDetailComponent],
  imports: [CommonModule, OrdersRoutingModule],
})
export class OrdersModule {}

Core vs Shared vs Feature Folders

A common, clear convention distinguishes three kinds of code: core for singletons used app-wide but not tied to any one feature, shared for reusable, presentation-only pieces with no business logic, and features for everything specific to one part of the domain.

Folder Example Contents
core/ AuthService, authGuard, authInterceptor
shared/ui/ ButtonComponent, SpinnerComponent, TruncatePipe
features/orders/ OrderListComponent, OrderService, orders.routes.ts

Common Mistakes

  • Organizing a large app purely by file type (components/, services/), scattering related feature code across the whole codebase.
  • Putting feature-specific logic into shared/ or core/, blurring the boundary between genuinely reusable code and one feature's business logic.
  • Letting one feature folder directly import another feature's internal components/services instead of communicating through a shared service or well-defined route boundary.
  • Not lazy-loading feature routes, missing an easy bundle-size win that a clean feature-folder structure naturally enables.

Key Takeaways

  • Feature modules (or feature folders, in standalone code) group everything related to one domain area together.
  • This organization scales better than organizing purely by file type as an application grows.
  • Feature folders map naturally onto lazy-loaded route boundaries.
  • core/, shared/, and features/ is a common, clear top-level convention for larger Angular apps.

Pro Tip

Resist the urge to put feature-specific code into shared/ just because it might be reused someday; wait until a second feature genuinely needs it, then move it, premature sharing usually creates more coupling than it saves.