Chapter 02 — Setup & The Nest CLI
Chapter 02 — Setup & The Nest CLI
Hey everyone! Welcome back to Namaste NestJS! 🙏
Enough theory — today we get our hands dirty. The great news? You will barely type any boilerplate. NestJS ships with a CLI (Command Line Interface) that scaffolds files, wires them up, and even writes test stubs for you. Think of the CLI as an assistant who does all the boring setup so you focus on logic.
By the end of this chapter you'll have a running server and understand every single file that created it. Let's go!
What we will cover:
- Prerequisites (Node version, what to install)
- Installing the Nest CLI
- Scaffolding your first app with
nest new - The project structure — what every file does
main.ts— the bootstrap file, line by line- The starter Module / Controller / Service
nest generate— the boilerplate superpower- Running, watching, and building
- Interview Questions
1. Prerequisites — What You Need First
Before Nest, you need Node.js. That's basically it.
┌─────────────────────────────────────────────────────────────┐ │ CHECKLIST BEFORE WE START │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ✔ Node.js (LTS, v18 or newer recommended) │ │ ✔ npm (comes with Node) │ │ ✔ A code editor (VS Code is ideal for TypeScript) │ │ │ └─────────────────────────────────────────────────────────────┘
Check your Node version first:
node -v # should print something like v18.17.0 or higher
Important: Nest needs a reasonably modern Node because it uses features TypeScript compiles down to. If node -v shows v14 or lower, update Node before continuing.
2. Installing the Nest CLI
We install the CLI globally so the nest command is available anywhere on your machine:
npm install -g @nestjs/cli # verify it worked: nest --version
In simple words: the -g flag means "global" — install it once, use it in every project. Now you have a brand-new command called nest.
WHAT THE CLI GIVES YOU: ─────────────────────── ✔ nest new → create a whole project ✔ nest generate → create controllers, services, modules... ✔ nest build → compile TypeScript to JavaScript ✔ nest start → run your app (with --watch for auto-reload)
3. Creating Your First App
One command builds the entire skeleton:
nest new my-first-app # the CLI will ask which package manager you want: # ❯ npm # yarn # pnpm # pick npm (or your favourite), hit Enter, and wait a moment.
When it finishes, jump in and start it:
cd my-first-app npm run start:dev // 👈 dev mode = auto-restarts when you save a file
Open your browser at http://localhost:3000 and you'll see Hello World! 🎉
┌─────────────────────────────────────────────────────────────┐ │ YOU JUST DID THIS: │ │ │ │ one command ──→ a full TypeScript backend │ │ with a running server, │ │ a sample route, and tests set up. │ │ │ │ In plain Express, all of that is manual. 😌 │ └─────────────────────────────────────────────────────────────┘
4. The Project Structure — What Every File Does
Open the folder. Don't panic at the file list — most of it is config you rarely touch. The part that matters is tiny: the src/ folder.
my-first-app/ ├── src/ ← 👈 YOUR CODE LIVES HERE │ ├── main.ts ← the entry point (bootstrap) │ ├── app.module.ts ← the ROOT module (ties everything together) │ ├── app.controller.ts ← a sample controller (routes) │ ├── app.service.ts ← a sample service (logic) │ └── app.controller.spec.ts ← a sample test file ├── test/ ← end-to-end (e2e) tests ├── node_modules/ ← installed packages (never edit) ├── package.json ← scripts + dependencies ├── tsconfig.json ← TypeScript settings └── nest-cli.json ← Nest CLI settings
Pro tip: 95% of your time is spent inside src/. Everything else is configuration the CLI already set up correctly.
5. main.ts — The Bootstrap File, Line by Line
This is where your app starts. It's small — let's read every line.
// src/main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
// 1. NestFactory builds the whole app starting from the ROOT module
const app = await NestFactory.create(AppModule);
// 2. Start listening for HTTP requests on port 3000
await app.listen(3000);
}
bootstrap();
Let's trace what happens when you run it:
LET'S TRACE IT BY HAND: npm run start:dev
──────────────────────────────────────────
1. bootstrap() runs
│
2. NestFactory.create(AppModule)
→ Nest reads AppModule
→ sees its controllers + providers
→ builds ("instantiates") all of them
→ wires dependencies together (DI)
│
3. app.listen(3000)
→ Express server starts on port 3000
▼
"Application is running on: http://localhost:3000" ✔
Q: Why is it async / await?
Because building the app and starting the server are asynchronous operations. NestFactory.create() returns a Promise, so we await it before the app is ready.
Note: AppModule is the single door Nest walks through to discover your entire app. Everything must eventually connect back to it. More on that in Chapter 05.
6. The Starter Trio — Module, Controller, Service
The CLI generated a mini version of the "3 building blocks" from Chapter 01. Let's read them.
app.module.ts — the root module:
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [], // other modules this one needs
controllers: [AppController],// the routes this module owns
providers: [AppService], // the logic this module owns (injectable)
})
export class AppModule {}
app.controller.ts — the route handler:
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller() // no prefix → handles routes at "/"
export class AppController {
constructor(private readonly appService: AppService) {} // 👈 service injected here
@Get() // handles GET /
getHello(): string {
return this.appService.getHello(); // delegate to the service
}
}
app.service.ts — the logic:
import { Injectable } from '@nestjs/common';
@Injectable() // 👈 "I can be injected"
export class AppService {
getHello(): string {
return 'Hello World!'; // the string you saw in the browser
}
}
Put together, that's the entire "Hello World" flow:
GET / ──→ AppController.getHello() ──→ AppService.getHello() ──→ "Hello World!"
(receptionist) (chef) (the food 🍽️)
7. nest generate — Your Boilerplate Superpower
Here's where the CLI truly shines. Instead of hand-creating files, you generate them — and Nest even updates the module for you.
# long form: nest generate module cats nest generate controller cats nest generate service cats # short form (same thing): nest g mo cats nest g co cats nest g s cats
What did that just do?
┌─────────────────────────────────────────────────────────────┐ │ `nest g resource cats` (the all-in-one command!) │ ├─────────────────────────────────────────────────────────────┤ │ │ │ Creates a folder src/cats/ with: │ │ ✔ cats.module.ts │ │ ✔ cats.controller.ts (+ .spec.ts test) │ │ ✔ cats.service.ts (+ .spec.ts test) │ │ ✔ dto/ and entities/ folders │ │ │ │ AND automatically registers CatsModule inside AppModule! │ │ (no manual wiring — this is the magic ✨) │ │ │ └─────────────────────────────────────────────────────────────┘
Pro tip: nest g resource cats even offers to generate a full CRUD REST API (or GraphQL/microservice) with all methods stubbed out. It's the fastest way to start a new feature.
Q: Why use the generator instead of copy-pasting files?
A: Three reasons — it follows the official naming convention, it auto-registers the module so you never forget the wiring, and it creates matching test files. Consistency for free.
8. Running, Watching, and Building
These are the scripts you'll live in, all defined in package.json:
| Command | What it does | When you use it |
|---|---|---|
npm run start | Runs the app once | Quick check |
npm run start:dev | Runs + auto-restarts on save (watch mode) | Everyday development ⭐ |
npm run start:debug | Watch mode + debugger attached | Hunting a bug |
npm run build | Compiles TS → JS into dist/ | Preparing for production |
npm run start:prod | Runs the compiled dist/ | In production |
In plain English: use start:dev while coding (it reloads instantly), and build + start:prod when deploying (raw JavaScript runs faster, no compiler in the loop).
Interview Questions — Quick Fire!
Q: What is the Nest CLI and why is it useful?
"The Nest CLI is a command-line tool that scaffolds and manages NestJS projects. It creates new apps with nest new, generates boilerplate like controllers and services with nest generate, and builds or runs the app. It enforces the official folder and naming conventions and auto-wires generated modules, which saves time and keeps projects consistent."
Q: What is the role of main.ts?
"main.ts is the entry point of a Nest application. It calls NestFactory.create with the root module to build the application instance, then calls app.listen to start the HTTP server. Any global setup — like enabling CORS, global pipes, or Swagger — is typically configured here before listen."
Q: What does NestFactory.create do?
"It bootstraps the application. Starting from the root module you pass it, Nest reads all the modules, controllers, and providers, instantiates them, resolves their dependencies through the DI container, and returns a ready application instance you can then start listening with."
Q: What's the difference between start:dev and start:prod?
"start:dev runs the app in watch mode, recompiling and restarting automatically whenever a file changes — ideal for development. start:prod runs the already-compiled JavaScript from the dist folder, which is faster and what you use in production after running the build command."
Q: What does `nest generate resource` create?
"It scaffolds a complete feature: a module, controller, and service, along with DTO and entity folders and test files. It can also generate full CRUD boilerplate for REST, GraphQL, or microservices, and it automatically registers the new module in the app module."
Key Points to Remember
| Concept | Key Takeaway |
|---|---|
| Nest CLI | Install globally; scaffolds and manages projects. |
| nest new | Creates a full project skeleton in one command. |
| src/ folder | Where your code lives; everything else is config. |
| main.ts | Entry point: NestFactory.create(AppModule) → app.listen(). |
| nest generate | Creates files AND auto-registers them in the module. |
| start:dev | Watch mode — your everyday command. |
What's Next?
You've got a running app and you understand what built it. In Chapter 03 we zoom into the first building block: Controllers. You'll learn routing, HTTP method decorators (@Get, @Post...), how to read route params, query strings, and the request body, and how to shape the response. This is where your API starts to feel real.
Keep coding, keep shipping! See you in the next one!
Post a Comment