Feature Folder Organization
Grouping code by feature keeps related components, routes, and services in one folder, making the codebase easier to navigate and maintain.
Feature Folder Structure
src/app/
├── core/ # Singleton services, guards, interceptors
│ ├── services/
│ │ ├── auth.service.ts
│ │ └── logger.service.ts
│ ├── guards/
│ │ └── auth.guard.ts
│ ├── interceptors/
│ │ └── auth.interceptor.ts
│ └── core.module.ts # Or provideCore() function
│
├── shared/ # Reusable components, pipes, directives
│ ├── components/
│ │ ├── button/
│ │ ├── modal/
│ │ └── card/
│ ├── pipes/
│ ├── directives/
│ └── shared.module.ts # Or standalone imports
│
├── features/ # Feature modules
│ ├── users/
│ │ ├── components/
│ │ │ ├── user-list/
│ │ │ ├── user-detail/
│ │ │ └── user-form/
│ │ ├── services/
│ │ │ └── user.service.ts
│ │ ├── models/
│ │ │ └── user.model.ts
│ │ ├── store/ # NgRx or signal state
│ │ │ ├── user.actions.ts
│ │ │ ├── user.reducer.ts
│ │ │ └── user.selectors.ts
│ │ └── users.routes.ts
│ │
│ ├── products/
│ │ ├── components/
│ │ ├── services/
│ │ ├── models/
│ │ └── products.routes.ts
│ │
│ └── dashboard/
│ ├── components/
│ └── dashboard.routes.ts
│
└── app.component.ts
Core vs Shared
| Folder | Purpose | Import Rule |
|---|---|---|
core/ |
Singletons (services, guards, interceptors) | Imported once at root |
shared/ |
Reusable UI (components, pipes, directives) | Imported by features |
features/ |
Feature-specific code | Not imported by other features |
Standalone Component Patterns
Standalone components import only the directives and pipes they actually use, making dependencies explicit.
Standalone Component Imports
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { ReactiveFormsModule } from '@angular/forms';
import { HighlightDirective } from '../../shared/directives/highlight.directive';
import { TruncatePipe } from '../../shared/pipes/truncate.pipe';
@Component({
selector: 'app-user-list',
standalone: true,
imports: [
CommonModule,
RouterModule,
ReactiveFormsModule,
HighlightDirective,
TruncatePipe,
],
template: `...`,
})
export class UserListComponent {}
Barrel Exports
// shared/index.ts
export * from './components/button/button.component';
export * from './components/modal/modal.component';
export * from './pipes/truncate.pipe';
export * from './directives/highlight.directive';
Feature Routes
// features/users/users.routes.ts
import { Routes } from '@angular/router';
export const USERS_ROUTES: Routes = [
{
path: '',
loadComponent: () =>
import('./components/user-list/user-list.component').then(m => m.UserListComponent),
},
{
path: ':id',
loadComponent: () =>
import('./components/user-detail/user-detail.component').then(m => m.UserDetailComponent),
},
];
Quiz
1. What is the benefit of feature folder organization?
2. What is the difference between core and shared folders?
3. How do standalone components declare dependencies?
Flashcards
Question
Benefit of feature folders?
Click to reveal answer
Answer
Related code co-located. Easier to navigate and maintain.
Question
Core vs shared?
Click to reveal answer
Answer
Core: singletons at root. Shared: reusable UI for features.
Question
Standalone component dependencies?
Click to reveal answer
Answer
imports array in @Component. Explicit and tree-shakable.
Revision Notes
Key Takeaways
- 1. Feature folders co-locate related code
- 2. Core: singletons. Shared: reusable UI. Features: feature-specific
- 3. Standalone components use explicit imports
- 4. Feature routes use lazy loading
Interview Tips
- • Explain the core/shared/features structure
- • Be ready to describe standalone component patterns
- • Mention barrel exports for clean imports
Cheat Sheet
Feature Folders Cheat Sheet
Structure:
core/ → Singletons (services, guards)
shared/ → Reusable UI (components, pipes)
features/ → Feature-specific code
Standalone imports:
@Component({
standalone: true,
imports: [CommonModule, RouterModule, MyPipe],
})