
Angular Module Design
- 413 installs
- 305 repo stars
- Updated March 4, 2026
- aj-geddes/useful-ai-prompts
angular-module-design is a Claude Code skill that architects scalable Angular applications using feature modules, lazy-loaded routes, shared libraries, dependency injection, and RxJS reactive patterns for enterprise fron
About
angular-module-design is a Claude Code skill from aj-geddes/useful-ai-prompts that guides feature-module architecture for large Angular applications. The skill covers NgModule declarations, lazy-loaded UsersRoutingModule patterns, service providers, ReactiveFormsModule imports, and RxJS-based state handling. Developers reach for it when organizing enterprise frontends with clear module boundaries, shared libraries, and optimized lazy routes instead of a monolithic AppModule. Reference guides document dependency injection and implementation steps with concrete UsersModule examples including UsersListComponent, UserDetailComponent, and UsersService wiring.
- Feature vs shared module splits
- Lazy-loaded routing design
- Dependency injection patterns
- Barrel exports and public APIs
- NgModule and standalone migration
Angular Module Design by the numbers
- 413 all-time installs (skills.sh)
- Ranked #657 of 2,245 Frontend Development skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/aj-geddes/useful-ai-prompts --skill angular-module-designAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 413 |
|---|---|
| repo stars | ★ 305 |
| Last updated | March 4, 2026 |
| Repository | aj-geddes/useful-ai-prompts ↗ |
How do you structure Angular feature modules and lazy routes?
Structure Angular apps with feature modules, shared libraries, lazy routes, dependency injection, and clean boundaries for scalable enterprise frontends.
Who is it for?
Angular developers refactoring monolithic apps into feature modules with lazy loading and clean dependency injection boundaries.
Skip if: Developers on small Angular standalone-component apps who do not need NgModule-based feature partitioning or lazy route architecture.
When should I use this skill?
An Angular codebase needs feature module boundaries, lazy routing, shared libraries, or RxJS service organization.
What you get
Feature NgModules, lazy routing modules, shared libraries, and DI service boundaries
- Feature module structure
- Lazy routing modules
- Shared library boundaries
By the numbers
- Part of useful-ai-prompts Frontend Development category with 12 related skills
- Documents UsersModule with list, detail, routing, and service components
Files
Angular Module Design
Table of Contents
Overview
Architect scalable Angular applications using feature modules, lazy loading, services, and RxJS for reactive programming patterns.
When to Use
- Large Angular applications
- Feature-based organization
- Lazy loading optimization
- Dependency injection patterns
- Reactive state management
Quick Start
Minimal working example:
// users.module.ts
import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { ReactiveFormsModule } from "@angular/forms";
import { UsersRoutingModule } from "./users-routing.module";
import { UsersListComponent } from "./components/users-list/users-list.component";
import { UserDetailComponent } from "./components/user-detail/user-detail.component";
import { UsersService } from "./services/users.service";
@NgModule({
declarations: [UsersListComponent, UserDetailComponent],
imports: [CommonModule, ReactiveFormsModule, UsersRoutingModule],
providers: [UsersService],
})
export class UsersModule {}Reference Guides
Detailed implementations in the references/ directory:
| Guide | Contents |
|---|---|
| Feature Module Structure | Feature Module Structure |
| Lazy Loading Routes | Lazy Loading Routes |
| Service with RxJS | Service with RxJS |
| Smart and Presentational Components | Smart and Presentational Components |
| Dependency Injection and Providers | Dependency Injection and Providers |
Best Practices
✅ DO
- Follow established patterns and conventions
- Write clean, maintainable code
- Add appropriate documentation
- Test thoroughly before deploying
❌ DON'T
- Skip testing or validation
- Ignore error handling
- Hard-code configuration values
Dependency Injection and Providers
Dependency Injection and Providers
// config.service.ts
import { Injectable } from "@angular/core";
interface AppConfig {
apiUrl: string;
environment: string;
}
@Injectable({ providedIn: "root" })
export class ConfigService {
private config: AppConfig = {
apiUrl: "https://api.example.com",
environment: "production",
};
get(key: keyof AppConfig): any {
return this.config[key];
}
}
// app.module.ts with providers
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { HttpClientModule, HTTP_INTERCEPTORS } from "@angular/common/http";
import { ConfigService } from "./services/config.service";
import { AuthInterceptor } from "./interceptors/auth.interceptor";
@NgModule({
imports: [BrowserModule, HttpClientModule],
providers: [
ConfigService,
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
],
})
export class AppModule {}Feature Module Structure
Feature Module Structure
// users.module.ts
import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { ReactiveFormsModule } from "@angular/forms";
import { UsersRoutingModule } from "./users-routing.module";
import { UsersListComponent } from "./components/users-list/users-list.component";
import { UserDetailComponent } from "./components/user-detail/user-detail.component";
import { UsersService } from "./services/users.service";
@NgModule({
declarations: [UsersListComponent, UserDetailComponent],
imports: [CommonModule, ReactiveFormsModule, UsersRoutingModule],
providers: [UsersService],
})
export class UsersModule {}Lazy Loading Routes
Lazy Loading Routes
// app-routing.module.ts
import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { DashboardComponent } from "./components/dashboard/dashboard.component";
const routes: Routes = [
{ path: "", component: DashboardComponent },
{
path: "users",
loadChildren: () =>
import("./features/users/users.module").then((m) => m.UsersModule),
},
{
path: "products",
loadChildren: () =>
import("./features/products/products.module").then(
(m) => m.ProductsModule,
),
},
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {}Service with RxJS
Service with RxJS
// users.service.ts
import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { BehaviorSubject, Observable, throwError } from "rxjs";
import { map, catchError, tap } from "rxjs/operators";
interface User {
id: number;
name: string;
email: string;
}
@Injectable({ providedIn: "root" })
export class UsersService {
private usersSubject = new BehaviorSubject<User[]>([]);
public users$ = this.usersSubject.asObservable();
constructor(private http: HttpClient) {}
getUsers(): Observable<User[]> {
return this.http.get<User[]>("/api/users").pipe(
tap((users) => this.usersSubject.next(users)),
catchError((error) => {
console.error("Error fetching users:", error);
return throwError(() => new Error("Failed to load users"));
}),
);
}
getUserById(id: number): Observable<User> {
return this.http.get<User>(`/api/users/${id}`);
}
createUser(user: Omit<User, "id">): Observable<User> {
return this.http.post<User>("/api/users", user).pipe(
tap((newUser) => {
const currentUsers = this.usersSubject.value;
this.usersSubject.next([...currentUsers, newUser]);
}),
);
}
updateUser(id: number, user: User): Observable<User> {
return this.http.put<User>(`/api/users/${id}`, user).pipe(
tap((updatedUser) => {
const currentUsers = this.usersSubject.value;
const index = currentUsers.findIndex((u) => u.id === id);
if (index !== -1) {
currentUsers[index] = updatedUser;
this.usersSubject.next([...currentUsers]);
}
}),
);
}
deleteUser(id: number): Observable<void> {
return this.http.delete<void>(`/api/users/${id}`).pipe(
tap(() => {
const currentUsers = this.usersSubject.value;
this.usersSubject.next(currentUsers.filter((u) => u.id !== id));
}),
);
}
}Smart and Presentational Components
Smart and Presentational Components
// users-list.component.ts (Smart)
import { Component, OnInit } from "@angular/core";
import { Observable } from "rxjs";
import { UsersService } from "../../services/users.service";
interface User {
id: number;
name: string;
email: string;
}
@Component({
selector: "app-users-list",
template: `
<div>
<h2>Users</h2>
<button (click)="addUser()">Add User</button>
<app-user-item
*ngFor="let user of users$ | async"
[user]="user"
(delete)="deleteUser($event)"
></app-user-item>
</div>
`,
})
export class UsersListComponent implements OnInit {
users$: Observable<User[]>;
constructor(private usersService: UsersService) {
this.users$ = this.usersService.users$;
}
ngOnInit(): void {
this.usersService.getUsers().subscribe();
}
addUser(): void {
// Navigation or modal logic
}
deleteUser(id: number): void {
this.usersService.deleteUser(id).subscribe();
}
}
// user-item.component.ts (Presentational)
import { Component, Input, Output, EventEmitter } from "@angular/core";
interface User {
id: number;
name: string;
email: string;
}
@Component({
selector: "app-user-item",
template: `
<div class="user-item">
<h3>{{ user.name }}</h3>
<p>{{ user.email }}</p>
<button (click)="onDelete()">Delete</button>
</div>
`,
styleUrls: ["./user-item.component.css"],
})
export class UserItemComponent {
@Input() user!: User;
@Output() delete = new EventEmitter<number>();
onDelete(): void {
this.delete.emit(this.user.id);
}
}// Component: [Name]
// TODO: Customize for your framework (React, Vue, Svelte, etc.)
import React from 'react';
interface Props {
// TODO: Define props
}
export function ComponentName({ }: Props) {
// TODO: Add state and effects
return (
<div>
{/* TODO: Add component markup */}
</div>
);
}
Related skills
How it compares
Use angular-module-design over generic frontend skills when NgModule feature boundaries and lazy route splitting are the primary architecture concern.
FAQ
What does angular-module-design help structure?
angular-module-design helps structure large Angular apps with feature modules, lazy-loaded routing modules, shared libraries, and per-module dependency injection. The skill includes UsersModule examples with list and detail components wired through UsersRoutingModule and UsersSer
Does angular-module-design cover lazy loading?
angular-module-design documents lazy route optimization via feature routing modules like UsersRoutingModule, keeping initial bundle size down. Developers split apps by domain features with NgModule boundaries instead of a single monolithic AppModule.
When should developers invoke angular-module-design?
angular-module-design fits large Angular applications needing feature-based organization, lazy loading, ReactiveFormsModule integration, and RxJS reactive patterns. Invoke it during frontend architecture planning before module sprawl accumulates.