On this page
What is NestJS? Architecture and first project
What is NestJS?
NestJS is a progressive Node.js framework for building efficient, reliable, and scalable server-side applications. It uses TypeScript by default and is heavily inspired by Angular's architecture — if you know Angular, you will feel right at home with NestJS.
Released in 2017 by Kamil Mysliwiec, NestJS has grown to become the most popular enterprise-grade framework for Node.js backends. Its combination of decorators, modules, dependency injection, and a rich ecosystem of official packages makes it ideal for REST APIs, microservices, WebSockets, and GraphQL servers.
Why NestJS over plain Express or Fastify?
Plain Express is powerful but gives you zero structure. Teams building large applications with Express often reinvent the same architectural patterns over and over: how to organize files, how to inject dependencies, how to validate requests, how to handle errors. NestJS answers all these questions with opinionated, well-tested conventions.
Key advantages of NestJS:
- TypeScript first — full type safety across the entire request lifecycle
- Dependency injection — clean, testable code without manual wiring
- Module system — feature isolation and encapsulation by default
- Decorator-based — controllers, services, guards, and pipes declared with readable decorators
- Platform agnostic — runs on Express or Fastify under the hood
- Rich ecosystem — official packages for TypeORM, JWT, WebSockets, Swagger, config, and more
Core concepts at a glance
NestJS applications are composed of four building blocks:
| Concept | Role |
|---|---|
| Module | Groups related controllers and providers |
| Controller | Handles HTTP requests and returns responses |
| Provider / Service | Contains business logic, injected where needed |
| Pipe / Guard / Interceptor | Cross-cutting concerns (validation, auth, logging) |
Installing and creating a project
Install the CLI globally:
npm install -g @nestjs/cliCreate a new project:
nest new bookstore-apiThe CLI asks about your preferred package manager (npm, yarn, or pnpm). After installation, your project structure looks like this:
bookstore-api/
src/
app.controller.ts # Root controller
app.controller.spec.ts
app.module.ts # Root module
app.service.ts # Root service
main.ts # Application entry point
test/
app.e2e-spec.ts
jest-e2e.json
nest-cli.json # CLI configuration
tsconfig.json
package.jsonRunning the application
cd bookstore-api
npm run start:devThe start:dev script runs the application with watch mode enabled using ts-node-dev. Any file change triggers an automatic restart. Open your browser at http://localhost:3000 and you will see Hello World!.
Understanding main.ts
The main.ts file is the entry point of every NestJS application. It uses NestFactory.create() to instantiate the application from the root module and then starts listening for connections.
The bootstrap function pattern is important: it is async because NestJS initializes all providers, runs lifecycle hooks, and may perform asynchronous operations before the server is ready. Always await the listen() call.
The request lifecycle
When a request arrives at a NestJS application, it travels through several layers in a specific order:
- Middleware — Express/Fastify middleware (logging, body parsing)
- Guards — Authentication and authorization checks
- Interceptors (before) — Transform requests, add metadata
- Pipes — Validate and transform request data
- Controller — Route handler executes business logic
- Interceptors (after) — Transform responses
- Exception filters — Catch and format errors
Understanding this lifecycle is essential for building robust APIs. Each layer has a single responsibility, which keeps your code clean and testable.
NestJS 11 highlights
NestJS 11 (released in 2025) ships with several improvements over version 10:
- Fastify v5 support — the high-performance HTTP adapter is fully compatible
- Node.js 20+ requirement — takes advantage of native fetch and improved ESM support
- Updated TypeORM and Mongoose integrations — aligned with their latest major versions
- Improved CLI generators — better monorepo support and resource generation
- Enhanced testing utilities — cleaner test module setup with
Test.createTestingModule()
Generating resources with the CLI
One of NestJS's productivity superpowers is the nest generate command (alias nest g):
# Generate a complete CRUD resource (module + controller + service + DTOs)
nest g resource books
# Generate individually
nest g module books
nest g controller books
nest g service booksThe nest g resource command is particularly useful: it asks whether you want REST, GraphQL, WebSocket, or microservice, and generates all the boilerplate including empty CRUD methods.
Project configuration
The nest-cli.json file controls the CLI behavior. The most important fields:
{
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"deleteOutDir": true,
"plugins": ["@nestjs/swagger"]
}
}The plugins array can include the Swagger plugin, which automatically extracts type information from DTOs without requiring manual decorators on every field.
TypeScript configuration
NestJS projects use strict TypeScript settings. The key options in tsconfig.json:
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"strictNullChecks": true,
"strict": true
}
}experimentalDecorators and emitDecoratorMetadata are mandatory for the decorator-based dependency injection system to work correctly. Without emitDecoratorMetadata, TypeScript does not emit type information at runtime, and NestJS cannot resolve constructor parameter types automatically.
What you will build in this course
Throughout this course, you will build a Bookstore REST API step by step. By the end, you will have a fully functional backend with:
- Books, authors, and categories resources
- JWT authentication with refresh tokens
- Role-based authorization
- File uploads
- Real-time notifications via WebSockets
- Swagger documentation
- Unit and integration tests
- Environment-based configuration
- Production-ready deployment setup
Each lesson introduces one concept and applies it directly to the bookstore project, so every piece of code you write has a concrete purpose.
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// Enable CORS for frontend applications
app.enableCors({
origin: ['http://localhost:4200'],
credentials: true,
});
// Global prefix for all routes
app.setGlobalPrefix('api');
await app.listen(3000);
console.log('Application running on: http://localhost:3000');
}
bootstrap();
Sign in to track your progress