NestJS Modules, Services & Controllers Skill
Purpose
You are a specialized assistant for structuring application features in NestJS using:
- Modules to group related capabilities
- Services to implement business logic and data orchestration
- Controllers to expose HTTP (or other transport) APIs
Use this skill to:
- Create new feature modules (e.g.
users, auth, posts, billing)
- Refactor or reorganize existing NestJS modules into a clean architecture
- Define DTOs, interfaces, and service APIs between layers
- Implement RESTful or RPC-like controllers with consistent patterns
- Wire features into
AppModule or root modules appropriately
- Keep code testable, maintainable, and TypeORM/Supabase-ready
Do not use this skill for:
- Project-level scaffolding → use
nestjs-project-scaffold
- Detailed authentication or security logic → use
nestjs-authentication
- TypeORM entities/migrations → use
nestjs-typeorm-integration / TypeORM skills
- Microservices transport-specific patterns → use dedicated microservices/queues skills
If CLAUDE.md exists, follow its guidelines on domain boundaries, naming, and architecture (e.g. “use hexagonal architecture”, “modules under src/modules”, etc.).
When To Apply This Skill
Trigger this skill when the user says things like:
- “Create a
users module with service and controller.”
- “Refactor this module structure, it’s messy.”
- “Add CRUD endpoints for this entity in NestJS.”
- “Split this monolithic module into smaller ones.”
- “Standardize how controllers and services are structured.”
- “Add a
billing module with clear service APIs and controllers.”
Avoid this skill when:
- Only routing (Next.js) is being changed (that’s frontend).
- Only database entities or migrations are being touched.
- Only auth, JWT, guards are being worked on → use auth-focused skill.
Default Conventions
Unless the project or CLAUDE.md specifies otherwise, assume:
Feature modules live under src/modules/<feature>/.
Each feature module contains at least:
src/modules/user/
user.module.ts
user.service.ts
user.controller.ts
dto/
create-user.dto.ts
update-user.dto.ts
entities/ # if using TypeORM in same folder (or under domain layer)
user.entity.ts
Naming is singular for module & service (UserModule, UserService), plural for controller route path (/users).
Controllers expose HTTP endpoints via @Controller('users') for REST by default.
Services are injectable, stateless, and DI-friendly.
High-Level Architecture Principles
When designing modules/services/controllers, follow these principles:
Feature-first organization
- Group by domain feature (users, auth, billing, orders), not by technical layer only.
- Each module should encapsulate its own controllers, services, and DTOs.
Separation of concerns
- Controllers:
- Handle HTTP specifics (params, query, body, response codes).
- Call services and map results to HTTP responses.
- Services:
- Contain business logic, orchestration, and integration with repositories/other services.
- Should not be aware of HTTP specifics.
- Repositories / persistence:
- Encapsulate DB access (TypeORM, Supabase, etc.).
- Can be separate injectable providers or TypeORM repositories.
Dependency injection & modularity
- Declare providers (services, repositories) in
providers array of the module.
- Export providers from a module only when they need to be used by other modules.
- Avoid circular dependencies; if needed, consider interfaces or refactoring modules.
DTOs & validation
- Use DTOs to define external API shapes (input/output).
- Decorate DTOs with
class-validator decorators (if validation is set up).
- Avoid using entities directly as request DTOs.
Consistent API patterns
- Use RESTful naming for controllers:
GET /users, GET /users/:id, POST /users, PATCH /users/:id, DELETE /users/:id.
- Use HTTP status codes appropriately:
201 Created on successful creation.
200 OK for reads, updates that return actual data.
204 No Content for deletions when no body is returned.
- Handle errors with Nest exceptions (
NotFoundException, BadRequestException, etc.).
Step-by-Step Workflow
When this skill is active, follow these steps:
1. Identify or define the feature
- Determine the feature name (e.g.
User, Auth, Post, Order).
- Determine what operations are needed:
- CRUD?
- Search/filter?
- Domain-specific actions (e.g. “activate user”, “cancel order”)?
- Determine how it fits into existing architecture:
- Does it depend on other modules?
- Will other modules depend on it?
2. Create the module structure
- Under
src/modules/<feature>/, create:
<feature>.module.ts
<feature>.service.ts
<feature>.controller.ts
dto/ and optionally entities/ or other subfolders.
Example module file outline:
// src/modules/user/user.module.ts
import { Module } from "@nestjs/common";
import { UserService } from "./user.service";
import { UserController } from "./user.controller";
@Module({
imports: [], // add other modules needed
controllers: [UserController],
providers: [UserService],
exports: [UserService], // export only if other modules need this service
})
export class UserModule {}
3. Design the service API
Start from use-cases (business operations), not raw DB operations.
Define methods such as:
// src/modules/user/user.service.ts
import { Injectable } from "@nestjs/common";
@Injectable()
export class UserService {
async create(dto: CreateUserDto) {
// TODO: implement create logic
}
async findAll(options?: ListUsersOptions) {
// TODO: implement listing logic
}
async findOne(id: string) {
// TODO: implement single lookup
}
async update(id: string, dto: UpdateUserDto) {
// TODO: implement update logic
}
async remove(id: string) {
// TODO: implement delete logic
}
}
Keep this layer free of HTTP-specific concerns.
4. Define DTOs
Create dto folder and DTO classes/types:
// src/modules/user/dto/create-user.dto.ts
import { IsEmail, IsString, MinLength } from "class-validator";
export class CreateUserDto {
@IsEmail()
email!: string;
@IsString()
@MinLength(8)
password!: string;
@IsString()
name!: string;
}
Similarly, UpdateUserDto (typically with partials) and query/filter DTOs.
This skill should ensure DTOs follow any validation rules set up in the project (e.g. using ValidationPipe).
5. Implement controller(s)
Map HTTP verbs and paths to service methods:
// src/modules/user/user.controller.ts
import {
Body,
Controller,
Delete,
Get,
Param,
Patch,
Post,
} from "@nestjs/common";
import { UserService } from "./user.service";
import { CreateUserDto } from "./dto/create-user.dto";
import { UpdateUserDto } from "./dto/update-user.dto";
@Controller("users")
export class UserController {
constructor(private readonly userService: UserService) {}
@Post()
create(@Body() dto: CreateUserDto) {
return this.userService.create(dto);
}
@Get()
findAll() {
return this.userService.findAll();
}
@Get(":id")
findOne(@Param("id") id: string) {
return this.userService.findOne(id);
}
@Patch(":id")
update(@Param("id") id: string, @Body() dto: UpdateUserDto) {
return this.userService.update(id, dto);
}
@Delete(":id")
remove(@Param("id") id: string) {
return this.userService.remove(id);
}
}
This skill should also:
- Add route-level decorators for auth, roles, etc., when combined with
nestjs-authentication skill.
- Use Nest’s parameter decorators for route params, queries, bodies, etc.
6. Wire module into the application
Register modules in AppModule or a root module:
// src/app.module.ts
import { Module } from "@nestjs/common";
import { UserModule } from "./modules/user/user.module";
@Module({
imports: [UserModule /*, other modules */],
})
export class AppModule {}
For monorepo or large apps, consider feature root modules (e.g. ApiModule) grouping submodules.
7. Refactor messy code into modules
When refactoring:
- Identify “god modules” that contain many unrelated features.
- Split into smaller feature modules:
- Move controllers, services, DTOs into their own
src/modules/<feature>/ subfolders.
- Update imports and
AppModule configuration.
- Ensure DI remains correct:
- Move providers into their new modules.
- Export providers from modules only when needed.
8. Keep testability in mind
- Structure services so they can be tested with mocks (e.g. mock repositories).
- Avoid static methods and global singletons in services.
- Controllers should depend only on service interfaces or concrete services, not DB clients directly.
Advanced Options (Optional but Supported)
This skill can also support:
- Multiple controllers per module (e.g. public vs admin controllers).
- Sub-modules inside a feature folder (e.g. splitting read vs write API contracts).
- CQRS pattern (commands/queries) if the project or
CLAUDE.md prefers it:
- Register command/handler pairs and query/handler pairs.
- GraphQL controllers/resolvers if the project uses
@nestjs/graphql. In that case:
- Controllers may be replaced or complemented by resolvers.
This skill should adapt based on existing project conventions.
Example Prompts That Should Use This Skill
- “Generate a
users module with CRUD endpoints and DTOs.”
- “Split this
app module into distinct users, posts, and comments modules.”
- “Create a
billing module with a service and controller skeleton.”
- “Refactor existing services/controllers to follow best practice layering.”
- “Add DTOs and proper method signatures for this existing module.”
For these tasks, rely on this skill to design and organize NestJS modules, services, and controllers,
while leaving ORM-specific details, auth logic, and project-level scaffolding to their dedicated skills.
1---2name: nestjs-modules-services-controllers3description: Use this skill whenever the user wants to design, create, refactor, or standardize NestJS modules, services, and controllers in a TypeScript NestJS project, following clean architecture, DI best practices, and consistent API patterns.4---5
6# NestJS Modules, Services & Controllers Skill
7
8## Purpose
9
10You are a specialized assistant for **structuring application features** in NestJS using:
11
12- **Modules** to group related capabilities
13- **Services** to implement business logic and data orchestration
14- **Controllers** to expose HTTP (or other transport) APIs
15
16Use this skill to:
17
18- Create new **feature modules** (e.g. `users`, `auth`, `posts`, `billing`)
19- Refactor or reorganize existing NestJS modules into a clean architecture
20- Define **DTOs**, **interfaces**, and **service APIs** between layers
21- Implement RESTful or RPC-like **controllers** with consistent patterns
22- Wire features into `AppModule` or root modules appropriately
23- Keep code testable, maintainable, and TypeORM/Supabase-ready
24
25Do **not** use this skill for:
26
27- Project-level scaffolding → use `nestjs-project-scaffold`
28- Detailed authentication or security logic → use `nestjs-authentication`
29- TypeORM entities/migrations → use `nestjs-typeorm-integration` / TypeORM skills
30- Microservices transport-specific patterns → use dedicated microservices/queues skills
31
32If `CLAUDE.md` exists, follow its guidelines on domain boundaries, naming, and architecture (e.g. “use hexagonal architecture”, “modules under src/modules”, etc.).
33
34---
35
36## When To Apply This Skill
37
38Trigger this skill when the user says things like:
39
40- “Create a `users` module with service and controller.”
41- “Refactor this module structure, it’s messy.”
42- “Add CRUD endpoints for this entity in NestJS.”
43- “Split this monolithic module into smaller ones.”
44- “Standardize how controllers and services are structured.”
45- “Add a `billing` module with clear service APIs and controllers.”
46
47Avoid this skill when:
48
49- Only routing (Next.js) is being changed (that’s frontend).
50- Only database entities or migrations are being touched.
51- Only auth, JWT, guards are being worked on → use auth-focused skill.
52
53---
54
55## Default Conventions
56
57Unless the project or `CLAUDE.md` specifies otherwise, assume:
58
59- Feature modules live under `src/modules/<feature>/`.
60- Each feature module contains at least:
61
62 ```text
63 src/modules/user/
64 user.module.ts
65 user.service.ts
66 user.controller.ts
67 dto/
68 create-user.dto.ts
69 update-user.dto.ts
70 entities/ # if using TypeORM in same folder (or under domain layer)
71 user.entity.ts
72 ```
73
74- Naming is singular for module & service (`UserModule`, `UserService`), plural for controller route path (`/users`).
75
76- Controllers expose HTTP endpoints via `@Controller('users')` for REST by default.
77- Services are injectable, stateless, and DI-friendly.
78
79---
80
81## High-Level Architecture Principles
82
83When designing modules/services/controllers, follow these principles:
84
851. **Feature-first organization**
86 - Group by domain feature (users, auth, billing, orders), not by technical layer only.
87 - Each module should encapsulate its own controllers, services, and DTOs.
88
892. **Separation of concerns**
90 - Controllers:
91 - Handle HTTP specifics (params, query, body, response codes).
92 - Call services and map results to HTTP responses.
93 - Services:
94 - Contain business logic, orchestration, and integration with repositories/other services.
95 - Should **not** be aware of HTTP specifics.
96 - Repositories / persistence:
97 - Encapsulate DB access (TypeORM, Supabase, etc.).
98 - Can be separate injectable providers or TypeORM repositories.
99
1003. **Dependency injection & modularity**
101 - Declare providers (services, repositories) in `providers` array of the module.
102 - Export providers from a module only when they need to be used by other modules.
103 - Avoid circular dependencies; if needed, consider interfaces or refactoring modules.
104
1054. **DTOs & validation**
106 - Use DTOs to define external API shapes (input/output).
107 - Decorate DTOs with `class-validator` decorators (if validation is set up).
108 - Avoid using entities directly as request DTOs.
109
1105. **Consistent API patterns**
111 - Use RESTful naming for controllers:
112 - `GET /users`, `GET /users/:id`, `POST /users`, `PATCH /users/:id`, `DELETE /users/:id`.
113 - Use HTTP status codes appropriately:
114 - `201 Created` on successful creation.
115 - `200 OK` for reads, updates that return actual data.
116 - `204 No Content` for deletions when no body is returned.
117 - Handle errors with Nest exceptions (`NotFoundException`, `BadRequestException`, etc.).
118
119---
120
121## Step-by-Step Workflow
122
123When this skill is active, follow these steps:
124
125### 1. Identify or define the feature
126
127- Determine the **feature name** (e.g. `User`, `Auth`, `Post`, `Order`).
128- Determine what operations are needed:
129 - CRUD?
130 - Search/filter?
131 - Domain-specific actions (e.g. “activate user”, “cancel order”)?
132- Determine how it fits into existing architecture:
133 - Does it depend on other modules?
134 - Will other modules depend on it?
135
136### 2. Create the module structure
137
138- Under `src/modules/<feature>/`, create:
139 - `<feature>.module.ts`
140 - `<feature>.service.ts`
141 - `<feature>.controller.ts`
142 - `dto/` and optionally `entities/` or other subfolders.
143
144Example module file outline:
145
146```ts
147// src/modules/user/user.module.ts
148import { Module } from "@nestjs/common";
149import { UserService } from "./user.service";
150import { UserController } from "./user.controller";
151
152@Module({
153 imports: [], // add other modules needed
154 controllers: [UserController],
155 providers: [UserService],
156 exports: [UserService], // export only if other modules need this service
157})
158export class UserModule {}
159```
160
161### 3. Design the service API
162
163- Start from **use-cases** (business operations), not raw DB operations.
164- Define methods such as:
165
166 ```ts
167 // src/modules/user/user.service.ts
168 import { Injectable } from "@nestjs/common";
169
170 @Injectable()
171 export class UserService {
172 async create(dto: CreateUserDto) {
173 // TODO: implement create logic
174 }
175
176 async findAll(options?: ListUsersOptions) {
177 // TODO: implement listing logic
178 }
179
180 async findOne(id: string) {
181 // TODO: implement single lookup
182 }
183
184 async update(id: string, dto: UpdateUserDto) {
185 // TODO: implement update logic
186 }
187
188 async remove(id: string) {
189 // TODO: implement delete logic
190 }
191 }
192 ```
193
194- Keep this layer free of HTTP-specific concerns.
195
196### 4. Define DTOs
197
198- Create `dto` folder and DTO classes/types:
199
200 ```ts
201 // src/modules/user/dto/create-user.dto.ts
202 import { IsEmail, IsString, MinLength } from "class-validator";
203
204 export class CreateUserDto {
205 @IsEmail()
206 email!: string;
207
208 @IsString()
209 @MinLength(8)
210 password!: string;
211
212 @IsString()
213 name!: string;
214 }
215 ```
216
217- Similarly, `UpdateUserDto` (typically with partials) and query/filter DTOs.
218- This skill should ensure DTOs follow any validation rules set up in the project (e.g. using `ValidationPipe`).
219
220### 5. Implement controller(s)
221
222- Map HTTP verbs and paths to service methods:
223
224 ```ts
225 // src/modules/user/user.controller.ts
226 import {
227 Body,
228 Controller,
229 Delete,
230 Get,
231 Param,
232 Patch,
233 Post,
234 } from "@nestjs/common";
235 import { UserService } from "./user.service";
236 import { CreateUserDto } from "./dto/create-user.dto";
237 import { UpdateUserDto } from "./dto/update-user.dto";
238
239 @Controller("users")
240 export class UserController {
241 constructor(private readonly userService: UserService) {}
242
243 @Post()
244 create(@Body() dto: CreateUserDto) {
245 return this.userService.create(dto);
246 }
247
248 @Get()
249 findAll() {
250 return this.userService.findAll();
251 }
252
253 @Get(":id")
254 findOne(@Param("id") id: string) {
255 return this.userService.findOne(id);
256 }
257
258 @Patch(":id")
259 update(@Param("id") id: string, @Body() dto: UpdateUserDto) {
260 return this.userService.update(id, dto);
261 }
262
263 @Delete(":id")
264 remove(@Param("id") id: string) {
265 return this.userService.remove(id);
266 }
267 }
268 ```
269
270- This skill should also:
271 - Add route-level decorators for auth, roles, etc., when combined with `nestjs-authentication` skill.
272 - Use Nest’s parameter decorators for route params, queries, bodies, etc.
273
274### 6. Wire module into the application
275
276- Register modules in `AppModule` or a root module:
277
278 ```ts
279 // src/app.module.ts
280 import { Module } from "@nestjs/common";
281 import { UserModule } from "./modules/user/user.module";
282
283 @Module({
284 imports: [UserModule /*, other modules */],
285 })
286 export class AppModule {}
287 ```
288
289- For monorepo or large apps, consider feature root modules (e.g. `ApiModule`) grouping submodules.
290
291### 7. Refactor messy code into modules
292
293When refactoring:
294
295- Identify “god modules” that contain many unrelated features.
296- Split into smaller feature modules:
297 - Move controllers, services, DTOs into their own `src/modules/<feature>/` subfolders.
298 - Update imports and `AppModule` configuration.
299- Ensure DI remains correct:
300 - Move providers into their new modules.
301 - Export providers from modules only when needed.
302
303### 8. Keep testability in mind
304
305- Structure services so they can be tested with mocks (e.g. mock repositories).
306- Avoid static methods and global singletons in services.
307- Controllers should depend only on service interfaces or concrete services, not DB clients directly.
308
309---
310
311## Advanced Options (Optional but Supported)
312
313This skill can also support:
314
315- **Multiple controllers per module** (e.g. public vs admin controllers).
316- **Sub-modules** inside a feature folder (e.g. splitting read vs write API contracts).
317- **CQRS pattern** (commands/queries) if the project or `CLAUDE.md` prefers it:
318 - Register command/handler pairs and query/handler pairs.
319- **GraphQL** controllers/resolvers if the project uses `@nestjs/graphql`. In that case:
320 - Controllers may be replaced or complemented by resolvers.
321
322This skill should adapt based on existing project conventions.
323
324---
325
326## Example Prompts That Should Use This Skill
327
328- “Generate a `users` module with CRUD endpoints and DTOs.”
329- “Split this `app` module into distinct `users`, `posts`, and `comments` modules.”
330- “Create a `billing` module with a service and controller skeleton.”
331- “Refactor existing services/controllers to follow best practice layering.”
332- “Add DTOs and proper method signatures for this existing module.”
333
334For these tasks, rely on this skill to design and organize NestJS modules, services, and controllers,
335while leaving ORM-specific details, auth logic, and project-level scaffolding to their dedicated skills.