Expert guidance for building TypeScript NestJS applications with modular architecture, dependency injection, and best practices for clean, maintainable backend services.
Expert guidance for building scalable, maintainable NestJS applications with TypeScript best practices.
You are an expert in TypeScript, Node.js, and NestJS framework. Follow these principles and patterns when writing backend code.
1. **Code Quality**
- Write concise, technical TypeScript code with accurate examples
- Use constructor injection for all dependencies
- Apply separation of concerns rigorously throughout the codebase
- Create separate services for each distinct logical domain
- Prefer iteration and modularization over code duplication
2. **Project Structure**
- Use lowercase with dashes for directory names (e.g., `product-order`, `user-profile`)
- Structure files: use a `services` folder when a module contains more than one service
- Define configuration-related classes inside a dedicated `config` directory
- Use a `lib` directory/module for tools that can be reused across multiple projects
3. **TypeScript Best Practices**
- Use TypeScript for all code
- Prefer `interface` over `type` for object definitions
- Implement injectable services using TypeScript interfaces
- Maintain strict type safety throughout the application
4. **Architecture Patterns**
- **Services**: Implement all application logic inside services
- **Controllers**: Keep controllers clean and focused only on HTTP request/response handling
- **Gateways**: Keep gateways clean and focused only on WebSocket event handling
- **Modules**: Use the `useClass` approach when registering modules with configuration dependencies
- **External Integration**: Create separate modules for external packages or tools that don't have native NestJS support
5. **Dependency Injection**
- Use constructor injection consistently
- Register all dependencies through NestJS dependency injection container
- Avoid manual instantiation of services
```typescript
// Example module structure
src/
├── config/ # Configuration classes
│ └── database.config.ts
├── lib/ # Reusable utilities
│ └── shared-tool/
├── product-order/ # Feature module
│ ├── services/ # Multiple services
│ │ ├── order.service.ts
│ │ └── payment.service.ts
│ ├── product-order.controller.ts
│ ├── product-order.module.ts
│ └── interfaces/
│ └── order.interface.ts
```
```typescript
// interfaces/user.interface.ts
export interface IUser {
id: string;
email: string;
name: string;
}
// services/user.service.ts
import { Injectable } from '@nestjs/common';
import { IUser } from '../interfaces/user.interface';
@Injectable()
export class UserService {
async findById(id: string): Promise<IUser> {
// Implementation
}
}
// user.controller.ts
import { Controller, Get, Param } from '@nestjs/common';
import { UserService } from './services/user.service';
@Controller('users')
export class UserController {
constructor(private readonly userService: UserService) {}
@Get(':id')
async getUser(@Param('id') id: string) {
return this.userService.findById(id);
}
}
```
```typescript
// config/database.config.ts
export class DatabaseConfig {
host: string;
port: number;
// ... other config
}
// database.module.ts
@Module({
providers: [
{
provide: DatabaseConfig,
useClass: DatabaseConfig,
},
DatabaseService,
],
exports: [DatabaseService],
})
export class DatabaseModule {}
```
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/nestjs-backend-development/raw