Getting Started with NestJS: Setting Up Your First Project and Understanding the Folder Structure
Welcome to the complete beginner's guide to NestJS! This comprehensive document will walk you through everything you need to know to start your journey with NestJS, one of the most powerful and scalable Node.js frameworks available today.
Whether you're transitioning from Express.js, learning backend development for the first time, or building your next enterprise application, NestJS provides the tools, structure, and best practices to make your development experience smooth and productive.
By the end of this guide, you'll understand what NestJS is, why you should choose it, how to set it up, and how to navigate your first project structure confidently.
1. What is NestJS?
NestJS is a progressive Node.js framework designed for building efficient, reliable, and scalable server-side applications. It's built on top of Express.js (though it can also use Fastify) and combines elements of Object-Oriented Programming (OOP), Functional Programming (FP), and Functional Reactive Programming (FRP).
Core Philosophy
NestJS was created to address the architectural challenges that developers face when building large-scale Node.js applications. While Express.js is powerful and flexible, it doesn't enforce any particular structure or architecture. This flexibility can lead to inconsistent code organization, making large projects difficult to maintain.
NestJS solves this by providing:
- Strong architectural patterns inspired by Angular
- Built-in dependency injection for modular code
- TypeScript support as a first-class citizen
- Clear separation of concerns through modules, controllers, and services
- Enterprise-grade tooling out of the box
What Makes NestJS Special?
NestJS bridges the gap between rapid development and enterprise-level scalability. It's used by companies worldwide ranging from startups building MVPs to large enterprises managing complex microservices architectures.
2. Why Choose NestJS? Key Advantages and Features
2.1 TypeScript-First Approach
Advantage: NestJS is built with TypeScript at its core, not as an afterthought. This means:
- Type Safety: Catch errors at compile-time rather than runtime
- Better IDE Support: Excellent autocompletion and IntelliSense in your code editor
- Self-Documenting Code: Type annotations serve as inline documentation
- 40% Improvement in Code Maintainability: According to NestJS's 2024 developer survey
Example: // Type-safe controller method @Get(':id') async getUser(@Param('id') id: string): Promise { return this.usersService.findOne(id); }
2.2 Modular Architecture
Advantage: Organize your application into logical, reusable modules:
- Feature Separation: Each feature lives in its own module
- Clear Dependencies: Import only what you need
- 50% Reduction in Onboarding Time: New developers understand code structure faster
- Scalability: Add new features without affecting existing code
Structure Example:
> >
1src/
2├── users/ # Users module
3├── products/ # Products module
4├── orders/ # Orders module
5└── app.module.ts # Root module that combines all2.3 Built-in Dependency Injection
Advantage: NestJS's powerful dependency injection system enables:
- Loose Coupling: Services don't depend on concrete implementations
- Easy Testing: Mock dependencies for unit tests
- Code Reuse: Inject services across your application
- Automatic Instance Management: Manage singleton, request, and transient scopes
Real-World Benefit: When your database library changes, update only one service. All controllers using that service automatically work with the new implementation.
2.4 Multiple Transport Layers
NestJS isn't limited to REST APIs. Build:
- REST APIs (HTTP)
- GraphQL APIs
- WebSocket Real-Time Applications
- Microservices (message brokers like RabbitMQ, Kafka)
- gRPC Services
- Server-Sent Events (SSE)
Use Case: Build a real-time chat application with WebSockets while maintaining the same clean NestJS architecture.
2.5 Built-in Security Features
- Authentication Strategies: JWT, OAuth, local authentication
- Authorization Guards: Role-based access control (RBAC)
- Validation Pipes: Automatic request validation
- Helmet Integration: Protection against common web vulnerabilities
- CORS Configuration: Built-in CORS support
2.6 Comprehensive Testing Support
NestJS comes with:
- Unit Testing: Jest pre-configured
- Integration Testing: Easy test database setup
- E2E Testing: Full application testing framework
- Mocking Utilities: Simple dependency mocking for tests
2.7 Cloud-Native Friendly
2025 Advantage: NestJS is optimized for modern deployment:
- Kubernetes Compatible: Works seamlessly with K8s
- Serverless Ready: Deploy to AWS Lambda, Google Cloud Functions
- Docker Friendly: Containerize easily
- Microservices Architecture: Native support for distributed systems
2.8 Rich Ecosystem (One-Stop Solution)
NestJS has official packages for:
- Databases: TypeORM, Prisma, Sequelize, MongoDB
- Real-Time: WebSockets, Socket.io
- Caching: Redis integration
- Message Queues: RabbitMQ, Kafka, NATS
- GraphQL: Apollo, Mercurius
- File Upload: Multer
- Authentication: Passport.js integration
- Logging: Winston, Pino
- Monitoring: OpenTelemetry
2.9 Express.js Compatibility
- Built on top of Express.js by default
- Access Express middleware directly if needed
- Easy migration from existing Express projects
- All Express knowledge is transferable
2.10 Industry Adoption
According to 2025 developer surveys:
- Enterprise Use: 60% of large companies choosing NestJS for new projects
- Developer Satisfaction: Among the highest-rated backend frameworks
- Job Market: Growing demand for NestJS developers in India and globally
3. System Requirements and Prerequisites
3.1 What You Need Before Starting
Hardware Requirements
- Processor: Any modern processor (Intel Core i3+, AMD Ryzen 3+, or equivalent)
- RAM: Minimum 2GB (4GB+ recommended)
- Storage: At least 500MB free space for Node.js, npm packages, and project files
Software Requirements
Node.js (Must-have)
- Minimum Version: Node.js 12.x
- Recommended Version: Node.js 18.x or later (LTS)
- Why: NestJS requires Node.js for the JavaScript runtime
npm (Node Package Manager) - Installed automatically with Node.js
- Minimum Version: npm 6.x
- Recommended Version: npm 8.x or later
Text Editor or IDE (Choose one)
- Recommended: Visual Studio Code (VS Code) - Free and lightweight
- Alternative: WebStorm, Sublime Text, or any code editor
3.2 Verifying Your Setup
Open your terminal/command prompt and run:
Check Node.js version
node -v
Check npm version
npm -v
Expected Output:
v18.16.0 # Node.js version
9.6.7 # npm version
If you see version numbers, you're ready to proceed!
3.3 Optional But Recommended
Git (Version Control)
- Why: Track your project changes, collaborate with others
- Download: https://git-scm.com
Postman or Thunder Client (API Testing)
- Why: Test your API endpoints during development
- Postman: https://www.postman.com/downloads
- Thunder Client: VS Code extension (free alternative)
4. Installation Guide: Step-by-Step
Step 1: Install Node.js
For Windows:
- Visit https://nodejs.org
- Download the LTS (Long Term Support) version
- Run the installer
- Follow the installation wizard (accept defaults)
- Restart your computer
For macOS:
Using Homebrew (recommended)
brew install node
Or download from https://nodejs.org
For Linux (Ubuntu/Debian):
Update package manager
sudo apt update
Install Node.js
sudo apt install nodejs npm
Step 2: Verify Installation
node -v
npm -v
You should see version numbers like v18.16.0 and 9.6.7.
Step 3: Install NestJS CLI Globally
The NestJS CLI is a powerful tool for creating and managing projects. Install it globally so you can use it anywhere:
npm install -g @nestjs/cli
Verify Installation:
nest --version10.2.8 (version number may vary).Step 4: Configure npm Package Manager (Optional)
NestJS CLI can use npm, yarn, or pnpm. By default, it uses npm. You can verify your npm is working:
npm config get registry
Should show: https://registry.npmjs.org/
Congratulations! You've successfully installed all prerequisites. You're ready to create your first NestJS project.
5. Creating Your First NestJS Project
5.1 Using NestJS CLI (Recommended for Beginners)
This is the easiest way to create a new project with all boilerplate code and configuration ready:
Create a new NestJS project
nest new my-first-app
Navigate to your project
Plain Textcd my-first-app
What the CLI Asks:
When you run nest new my-first-app, the CLI will ask:
Which package manager would you ❤️ to use? (Use arrow keys)
Plain Text1❯ npm 2 yarn 3 pnpm
Choose npm (press Enter). The CLI will:
- Create a project folder named
my-first-app - Initialize package.json
- Install all necessary dependencies (this takes a minute)
- Create the initial project structure
- Generate example files (controller, service, module)
5.2 What Happens Behind the Scenes
The NestJS CLI essentially:
- Creates a new folder with your project name
- Initializes a Git repository
- Creates a
package.jsonfile with NestJS dependencies - Installs all npm packages
- Creates the basic folder structure
- Generates starter files (main.ts, app.module.ts, etc.)
- Configures TypeScript
5.3 Starting Your Application
Navigate to your project and start the development server:
Plain Text1cd my-first-app 2npm run start
Expected Output:
[NestFactory] Starting Nest application... [InstanceLoader] AppModule dependencies initialized [RoutesResolver] AppModule { ... }: mapped { /: GET } [RouterExplorer] Mapped { /, GET } route [NestApplication] Nest application successfully started Application listening on port 3000
Your First Server is Running! 🎉
Open your browser and go to: http://localhost:3000
You should see: Hello World!
5.4 Development Mode with Hot Reload
For a better development experience, use the watch mode which automatically restarts your app when you make changes:
Plain Textnpm run start:dev
Advantages of Watch Mode:
- Automatically restarts on file changes
- Faster than stopping and restarting manually
- Shows errors immediately in the terminal
6. Understanding the Project Structure
6.1 Complete Folder Tree
When you create a NestJS project with nest new my-first-app, here's what gets generated:
my-first-app/ ├── src/ # Source code directory │ ├── app.controller.ts # Main controller │ ├── app.controller.spec.ts # Unit tests for controller │ ├── app.module.ts # Root module │ ├── app.service.ts # Business logic service │ └── main.ts # Application entry point │ ├── test/ # E2E test files │ ├── app.e2e-spec.ts │ └── jest-e2e.json │ ├── node_modules/ # Installed packages (don't modify) │ ├── .gitignore # Files to ignore in Git │ ├── .prettierrc # Code formatting config │ ├── eslintrc.js # Linting rules │ ├── nest-cli.json # NestJS CLI configuration │ ├── package.json # Project metadata and dependencies │ ├── package-lock.json # Locked dependency versions │ ├── README.md # Project documentation │ ├── tsconfig.json # TypeScript configuration │ └── tsconfig.build.json # TypeScript build config
6.2 Detailed File Explanations
src/main.ts - The Application Entry Point
This is the first file that runs when your application starts:
Plain Text1import { NestFactory } from '@nestjs/core'; 2import { AppModule } from './app.module'; 3 4async function bootstrap() { 5 const app = await NestFactory.create(AppModule); 6 await app.listen(3000); 7} 8bootstrap();
What it does:
- Imports NestFactory (core utility)
- Imports AppModule (root module)
- Creates the NestJS application
- Starts listening on port 3000
Important: You rarely modify this file. It's the bootstrap sequence that initializes your entire application.
src/app.module.ts - The Root Module
Every NestJS application has at least one module, and the root module that combines everything:
Plain Text1import { Module } from '@nestjs/common'; 2import { AppController } from './app.controller'; 3import { AppService } from './app.service'; 4 5@Module({ 6 imports: [], 7 controllers: [AppController], 8 providers: [AppService], 9}) 10export class AppModule {}
Key Concepts:
- @Module(): Decorator that marks a class as a module
- imports: Other modules this module depends on
- controllers: HTTP request handlers
- providers: Services and other injectable classes
Analogy: Think of a module as a self-contained feature. A large application has many modules (Users, Products, Orders), all combined in AppModule.
src/app.controller.ts - Handles HTTP Requests
Controllers define your API endpoints:
Plain Text1import { Controller, Get } from '@nestjs/common'; 2import { AppService } from './app.service'; 3 4@Controller() 5export class AppController { 6 constructor(private readonly appService: AppService) {} 7 8 @Get() 9 getHello(): string { 10 return this.appService.getHello(); 11 } 12}
Key Parts:
- @Controller(): Marks class as a controller
- @Get(): HTTP GET route (POST, PUT, DELETE available too)
- constructor: Dependency injection - AppService is automatically provided
- getHello(): Handler method for GET requests
Example Endpoints: @Get('users') // GET /users @Get('users/:id') // GET /users/123 @Post('users') // POST /users @Put('users/:id') // PUT /users/123 @Delete('users/:id') // DELETE /users/123
src/app.service.ts - Business Logic
Services contain reusable business logic:
Plain Text1import { Injectable } from '@nestjs/common'; 2 3@Injectable() 4export class AppService { 5 getHello(): string { 6 return 'Hello World!'; 7 } 8}
Responsibilities:
- Fetch data from databases
- Call external APIs
- Process business logic
- Handle complex calculations
Separation of Concerns: Controllers handle HTTP, services handle logic.
src/app.controller.spec.ts - Unit Tests
Test your controller:
Plain Text1import { Test, TestingModule } from '@nestjs/testing'; 2import { AppController } from './app.controller'; 3import { AppService } from './app.service'; 4 5describe('AppController', () => { 6 let appController: AppController; 7 let appService: AppService; 8 9 beforeEach(async () => { 10 const module: TestingModule = await Test.createTestingModule({ 11 controllers: [AppController], 12 providers: [AppService], 13 }).compile(); 14 15 appController = module.get(AppController); 16 appService = module.get(AppService); 17 }); 18 19 it('should return "Hello World!"', () => { 20 expect(appController.getHello()).toBe('Hello World!'); 21 }); 22});
Run tests with: npm run test
Configuration Files
package.json - Project Metadata
Plain Text1{ 2 "name": "my-first-app", 3 "version": "0.0.1", 4 "description": "NestJS project", 5 "author": "Your Name", 6 "private": true, 7 "license": "MIT", 8 "scripts": { 9 "start": "nest start", 10 "start:dev": "nest start --watch", 11 "start:debug": "nest start --debug --watch", 12 "build": "nest build", 13 "test": "jest", 14 "test:watch": "jest --watch", 15 "test:cov": "jest --coverage" 16 }, 17 "dependencies": { 18 "@nestjs/common": "^10.0.0", 19 "@nestjs/core": "^10.0.0", 20 "@nestjs/platform-express": "^10.0.0", 21 "reflect-metadata": "^0.1.13", 22 "rxjs": "^7.8.1" 23 }, 24 "devDependencies": { 25 "@types/express": "^4.17.17", 26 "@types/jest": "^29.5.2", 27 "@types/node": "^20.3.1", 28 "typescript": "^5.1.3" 29 } 30}
tsconfig.json - TypeScript Settings
Plain Text1{ 2 "compilerOptions": { 3 "module": "commonjs", 4 "target": "ES2021", 5 "lib": ["ES2021"], 6 "strict": true, 7 "esModuleInterop": true, 8 "skipLibCheck": true, 9 "forceConsistentCasingInFileNames": true 10 } 11}
nest-cli.json - NestJS CLI Configuration
Plain Text1{ 2 "collection": "@nestjs/schematics", 3 "sourceRoot": "src", 4 "compilerOptions": { 5 "deleteOutDir": true 6 } 7}
6.3 Organizing Larger Projects
As your application grows, you'll want to organize code better. Here's a recommended structure for multiple features:
src/ ├── common/ # Shared across entire app │ ├── decorators/ # Custom decorators │ ├── filters/ # Exception filters │ ├── guards/ # Authentication guards │ ├── interceptors/ # Response transformation │ ├── middleware/ # Express middleware │ └── pipes/ # Validation pipes │ ├── config/ # Configuration management │ ├── database.config.ts │ └── app.config.ts │ ├── modules/ # Feature modules │ ├── users/ │ │ ├── users.module.ts │ │ ├── users.controller.ts │ │ ├── users.service.ts │ │ ├── dto/ │ │ │ ├── create-user.dto.ts │ │ │ └── update-user.dto.ts │ │ └── entities/ │ │ └── user.entity.ts │ │ │ ├── products/ │ │ ├── products.module.ts │ │ ├── products.controller.ts │ │ ├── products.service.ts │ │ ├── dto/ │ │ └── entities/ │ │ │ └── orders/ │ ├── orders.module.ts │ ├── orders.controller.ts │ ├── orders.service.ts │ ├── dto/ │ └── entities/ │ ├── database/ # Database-related code │ └── migrations/ │ ├── app.module.ts # Root module └── main.ts # Entry point
Benefits of This Structure:
- Scalability: Easy to add new features
- Maintainability: Each feature is self-contained
- Testing: Isolated modules are easier to test
- Collaboration: Multiple developers work on different modules
7. Core Concepts and Building Blocks
7.1 Modules - The Foundation
What is a Module?
A module is a class decorated with @Module() that organizes related code. Think of it as a container for related features.
Creating a Users Module:
Generate a module automatically
nest generate module users
Generate controller for users
nest generate controller users
Generate service for users
nest generate service users
This creates: users/ ├── users.module.ts ├── users.controller.ts ├── users.service.ts └── users.controller.spec.ts
users.module.ts: import { Module } from '@nestjs/common'; import { UsersController } from './users.controller'; import { UsersService } from './users.service';
@Module({ controllers: [UsersController], providers: [UsersService], exports: [UsersService], // Available to other modules }) export class UsersModule {}
app.module.ts (Updated): import { Module } from '@nestjs/common'; import { UsersModule } from './users/users.module'; import { AppController } from './app.controller'; import { AppService } from './app.service';
@Module({ imports: [UsersModule], // Import UsersModule controllers: [AppController], providers: [AppService], }) export class AppModule {}
Key Points:
- Import modules in AppModule to use them
- Services created in one module are available throughout the app
- Use
exportsto make services available to other modules
7.2 Controllers - Request Handlers
Controllers define API endpoints and handle HTTP requests.
users.controller.ts: import { Controller, Get, Post, Body, Param, Delete, Put } from '@nestjs/common'; import { UsersService } from './users.service'; import { CreateUserDto } from './dto/create-user.dto'; import { UpdateUserDto } from './dto/update-user.dto';
@Controller('users') // Base route: /users export class UsersController { constructor(private readonly usersService: UsersService) {}
// GET /users @Get() findAll() {
return this.usersService.findAll();}
// GET /users/:id @Get(':id') findOne(@Param('id') id: string) {
return this.usersService.findOne(+id);}
// POST /users @Post() create(@Body() createUserDto: CreateUserDto) {
return this.usersService.create(createUserDto);}
// PUT /users/:id @Put(':id') update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
return this.usersService.update(+id, updateUserDto);}
// DELETE /users/:id @Delete(':id') remove(@Param('id') id: string) {
return this.usersService.remove(+id);} }
Common Decorators:
@Controller(path)- Define controller base path@Get(),@Post(),@Put(),@Delete()- HTTP methods@Param(key)- Get URL parameters (/users/:id)@Query(key)- Get query string (?page=1)@Body()- Get request body@Headers(name)- Get specific header
7.3 Services - Business Logic
Services contain reusable business logic and are injectable throughout your app.
users.service.ts: import { Injectable } from '@nestjs/common'; import { CreateUserDto } from './dto/create-user.dto'; import { UpdateUserDto } from './dto/update-user.dto';
@Injectable() export class UsersService { private users = []; // In-memory storage (temporary)
create(createUserDto: CreateUserDto) {
Plain Text1const user = { 2 id: this.users.length + 1, 3 ...createUserDto, 4 createdAt: new Date(), 5}; 6this.users.push(user); 7return user;
}
findAll() {
return this.users;}
findOne(id: number) {
return this.users.find(user => user.id === id);}
update(id: number, updateUserDto: UpdateUserDto) {
Plain Text1const user = this.findOne(id); 2if (user) { 3 Object.assign(user, updateUserDto); 4} 5return user;
}
remove(id: number) {
Plain Text1const index = this.users.findIndex(user => user.id === id); 2if (index > -1) { 3 return this.users.splice(index, 1); 4}
} }
7.4 DTOs - Data Validation
DTOs (Data Transfer Objects) define the shape of data and enable validation.
dto/create-user.dto.ts: export class CreateUserDto { name: string; email: string; age: number; }
Using DTOs with Validation (Advanced): npm install class-validator class-transformer
Enhanced DTO: import { IsString, IsEmail, IsNumber, Min, Max } from 'class-validator';
export class CreateUserDto { @IsString() name: string;
@IsEmail() email: string;
@IsNumber() @Min(18) @Max(100) age: number; }
7.5 Dependency Injection - The Magic Behind the Scenes
What is Dependency Injection?
Instead of a class creating its own dependencies, NestJS provides (injects) them. This makes code testable and maintainable.
Without Dependency Injection (BAD): export class UsersService { private db = new Database(); // Hard-coded dependency
getUser(id: number) {
return this.db.query(`SELECT * FROM users WHERE id = ${id}`);} }
Problems:
- Hard to test (can't use a fake database)
- Tightly coupled to Database class
- Can't swap implementations
With Dependency Injection (GOOD): @Injectable() export class UsersService { constructor(private readonly db: DatabaseService) {} // Injected
getUser(id: number) {
return this.db.query(`SELECT * FROM users WHERE id = ${id}`);} }
Benefits:
- Testable: Pass a mock database in tests
- Loosely coupled: Can change database implementation
- Flexible: Different implementations for different environments
How NestJS DI Works:
// NestJS automatically creates singleton instance of DatabaseService // Injects it into UsersService constructor // Any component needing DatabaseService gets the same instance
@Module({ providers: [DatabaseService, UsersService], }) export class AppModule {}
7.6 Scopes - Lifecycle of Instances
NestJS supports different scopes for service instances:
Singleton (Default): @Injectable({ scope: Scope.DEFAULT }) // One instance for entire app export class UsersService {}
Request: import { Injectable, Scope } from '@nestjs/common';
@Injectable({ scope: Scope.REQUEST }) // New instance per HTTP request export class UsersService {}
Transient: @Injectable({ scope: Scope.TRANSIENT }) // New instance every time export class UsersService {}
When to Use:
- Singleton: Most services (database connections, utilities)
- Request: Services that need request-specific data
- Transient: Rarely needed (highly specialized use cases)
8. Running Your Application
8.1 Development Mode (Recommended for Learning)
npm run start:dev
Features:
- Automatically restarts on file changes
- Shows errors immediately
- Best for rapid development
Output: [1] 12345 - 01/15/2025, 10:30:00 AM [NestFactory] Starting Nest application... [1] 12345 - 01/15/2025, 10:30:01 AM [InstanceLoader] AppModule dependencies initialized [1] 12345 - 01/15/2025, 10:30:01 AM [RoutesResolver] AppModule: mapped { /: GET, /users: GET ... [1] 12345 - 01/15/2025, 10:30:01 AM [RouterExplorer] Mapped { /, GET } route [1] 12345 - 01/15/2025, 10:30:01 AM [RouterExplorer] Mapped { /users, GET } route [1] 12345 - 01/15/2025, 10:30:01 AM [NestApplication] Nest application successfully started [1] 12345 - 01/15/2025, 10:30:01 AM Application listening on port 3000
Open browser: http://localhost:3000
8.2 Production Build
Build the application
npm run build
Start production build
npm run start:prod
This creates an optimized dist/ folder ready for deployment.
8.3 Testing
Run all tests
npm run test
Run tests in watch mode
npm run test:watch
Run with coverage report
npm run test:cov
8.4 Common Development Commands
Watch mode for development
npm run start:dev
Debug mode (connect debugger)
npm run start:debug
Run tests
npm run test
Run tests with coverage
npm run test:cov
Build for production
npm run build
Run production version
npm run start:prod
Lint code
npm run lint
9. Next Steps and Best Practices
9.1 Essential Learning Path
Week 1-2: Fundamentals
- Understand Modules, Controllers, Services
- Practice creating CRUD endpoints
- Learn about DTOs and validation
Week 3-4: Intermediate
- Implement authentication (JWT)
- Connect to a database (TypeORM/Prisma)
- Add middleware and pipes
- Write unit tests
Week 5-6: Advanced
- Implement guards and interceptors
- Handle exceptions properly
- Create custom decorators
- Set up error handling
9.2 Best Practices
1. Modular Organization ✅ Good: Separate features into modules ✅ Good: Keep related code together ❌ Bad: Single module with everything ❌ Bad: No clear separation of concerns
2. Naming Conventions ✅ users.service.ts (services) ✅ users.controller.ts (controllers) ✅ users.module.ts (modules) ✅ create-user.dto.ts (DTOs) ✅ user.entity.ts (database entities)
3. Error Handling import { HttpException, HttpStatus } from '@nestjs/common';
@Get(':id') async getUser(@Param('id') id: string) { const user = await this.usersService.findOne(+id);
if (!user) {
throw new HttpException('User not found', HttpStatus.NOT_FOUND);}
return user; }
4. Validation import { IsEmail, IsString, Min, Max } from 'class-validator';
export class CreateUserDto { @IsString() name: string;
@IsEmail() email: string;
@Min(18) @Max(100) age: number; }
5. Environment Variables
Install dotenv
npm install @nestjs/config
Create .env file
DATABASEURL=postgres://user:password@localhost/dbname APIPORT=3000 NODE_ENV=development
6. Logging import { Logger } from '@nestjs/common';
export class UsersService { private readonly logger = new Logger(UsersService.name);
findAll() {
Plain Text1this.logger.log('Fetching all users'); 2return this.users;
} }
9.3 Recommended Packages for Beginners
Database ORM
npm install typeorm @nestjs/typeorm pg
Validation
npm install class-validator class-transformer
Environment variables
npm install @nestjs/config
Authentication
npm install @nestjs/jwt passport passport-jwt
API documentation
npm install @nestjs/swagger swagger-ui-express
9.4 Resources for Continued Learning
Official Documentation
- NestJS Docs: https://docs.nestjs.com
- NestJS GitHub: https://github.com/nestjs/nest
Community
- NestJS Discord: https://discord.gg/nestjs
- Stack Overflow: Tag #nestjs
Courses & Tutorials
- Official NestJS course on NestJS.com
- FreeCodeCamp NestJS tutorials
- Udemy courses (search "Complete NestJS Course")
Indian Developer Resources
- DevBlogger.in (Your platform!)
- Dev.to NestJS articles
- Hashnode NestJS community
10. Troubleshooting Common Issues
Issue 1: "Command 'nest' not found"
Problem: When running nest new app, you get command not found error.
Solution:
Reinstall NestJS CLI globally
npm install -g @nestjs/cli@latest
Verify installation
nest --version
If still not working, use npx
npx @nestjs/cli new my-app
Issue 2: Port 3000 Already in Use
Problem: Error message: "EADDRINUSE: address already in use :::3000"
Solution:
Option 1: Kill the process using port 3000
On Windows (PowerShell)
Get-Process -Id (Get-NetTCPConnection -LocalPort 3000).OwningProcess | Stop-Process -Force
On macOS/Linux
lsof -ti:3000 | xargs kill -9
Option 2: Use different port
In main.ts
await app.listen(3001); // Use different port
Issue 3: Module Not Found Error
Problem: Error: "Cannot find module '@nestjs/common'"
Solution:
Reinstall dependencies
npm install
Or if using yarn
yarn install
Clear cache and reinstall
npm cache clean --force rm -rf node_modules package-lock.json npm install
Issue 4: TypeScript Compilation Errors
Problem: Various TypeScript errors during build
Solution:
Check TypeScript version
npm list typescript
Update TypeScript
npm install -D typescript@latest
Clear build cache
npm run build
Check tsconfig.json is correct
Issue 5: Watch Mode Not Detecting Changes
Problem: Changes to files don't trigger restart in dev mode
Solution:
Stop the process (Ctrl+C)
Clear and restart
npm run start:dev
Or check if files are being watched
npm run start:dev --verbose
Issue 6: Tests Failing
Problem: Jest tests won't run or all tests fail
Solution:
Clear Jest cache
npm run test -- --clearCache
Run tests with more info
npm run test -- --verbose
Check test configuration in jest config
Issue 7: Out of Memory During Build
Problem: "JavaScript heap out of memory" error
Solution:
Increase Node memory limit
export NODE_OPTIONS="--max-old-space-size=4096" npm run build
On Windows (PowerShell)
$env:NODE_OPTIONS="--max-old-space-size=4096" npm run build
Issue 8: Dependency Version Conflicts
Problem: npm install fails due to version conflicts
Solution:
Use npm ci (clean install)
npm ci
Or force install
npm install --legacy-peer-deps
Check package versions
npm outdated
Conclusion
Congratulations! You now have a comprehensive understanding of:
✅ What NestJS is and why it's powerful ✅ How to install and set up NestJS projects ✅ The structure of a NestJS application ✅ Core concepts: Modules, Controllers, Services, Dependency Injection ✅ How to run and develop applications ✅ Best practices for building scalable applications ✅ How to troubleshoot common issues
Your Next Steps:
Set Up Your First Project nest new my-learning-project cd my-learning-project npm run start:dev
Create Your First Feature nest generate module products nest generate controller products nest generate service products
Build a Simple CRUD API
- Create endpoints for creating, reading, updating, deleting products
- Add validation with DTOs
- Test with Postman
Connect to a Database
- Install TypeORM or Prisma
- Learn about entities and migrations
- Persist data to PostgreSQL or MongoDB
Add Authentication
- Implement JWT authentication
- Create login/register endpoints
- Protect endpoints with guards
Share Your Learning
- Write about your journey on DevBlogger.in
- Share code on GitHub
- Help other beginners in the community
Remember:
- Start Small: Master basics before advanced features
- Read Documentation: NestJS docs are excellent
- Practice: Build multiple projects to reinforce learning
- Build Projects: Theory + practice = mastery
- Join Community: Connect with other NestJS developers
Quick Reference Cheat Sheet
Installation
npm install -g @nestjs/cli nest new my-app cd my-app
Development
npm run start:dev # Watch mode npm run test # Run tests npm run test:watch # Watch tests npm run build # Production build npm run start:prod # Run production build
Generate Components
nest generate module name # Create module nest generate controller name # Create controller nest generate service name # Create service nest generate pipe name # Create pipe nest generate guard name # Create guard
Key Decorators
@Module() # Mark class as module @Controller(path) # Mark class as controller @Injectable() # Mark class as injectable service @Get(), @Post(), @Put(), @Delete() # HTTP methods @Param(), @Query(), @Body() # Request data
Additional Resources
Official Links
- NestJS Official: https://nestjs.com
- Documentation: https://docs.nestjs.com
- GitHub Repository: https://github.com/nestjs/nest
- Awesome NestJS: https://github.com/juliandavidmr/awesome-nestjs
For Indian Developers
- DevBlogger.in: Your learning platform
- Learn Node.js best practices
- Connect with Indian tech community
- Build portfolio projects
Happy Coding! 🚀
Remember: Every expert was once a beginner. Keep building, keep learning, and don't hesitate to seek help from the community!