How to Set Up Your First NestJS Project
So, you have heard that NestJS is clean, structured, scalable, and probably a better long-term choice than letting your backend turn into a folder full of “final-final-real-final.js”.
Nice.
Now it is time to actually build your first project.
In this guide, we will go step by step and keep it beginner-friendly.
No weird shortcuts.
No assuming you already know the entire Node.js ecosystem by heart.
By the end, you will have:
- Node.js installed
- Nest CLI installed
- your first NestJS project created
- the app running locally
- a clear understanding of what the generated project structure is doing
Let’s get into it.
What you need before you start
Before creating a NestJS project, you need a few basics installed on your machine:
- **Node.js**
- **npm** (comes with Node.js)
- **A code editor**, like VS Code
- **A terminal**
For production-style development, Node recommends using an LTS release rather than a short-lived current release, and as of early April 2026 Node 24 is the latest LTS line.
If you already have Node installed, you can check your version with:
node -v
npm -vIf those commands work, great.
You are already in decent shape.
If not, install Node.js first, then come back with confidence and a slightly stronger terminal presence.
Step 1: Install the Nest CLI
The easiest way to create a NestJS app is with the Nest CLI.
Install it globally with:
npm i -g @nestjs/cli
This is still the standard setup command in the current Nest “First steps” guide.
Why use the CLI?
Because it saves you from doing boring setup manually.
It creates the starter project, adds the core files, and gives you useful generators later for things like modules, controllers, and services. Nest’s CLI command reference documents nest new, nest start, and nest generate for these workflows.
You can verify the CLI is installed with:
nest --versionStep 2: Create Your First NestJS Project
Now create a new project:
nest new my-first-nest-appNest will ask you to choose a package manager, usually:
- npm
- yarn
- pnpm
Pick the one you are comfortable with.
Once you confirm, the CLI will:
- create a new folder
- install dependencies
- generate starter files
- prepare a working NestJS app
That is exactly what the current CLI docs describe for nest new: it creates the folder, adds config files, builds /src and /test, and initializes starter app files.
If you want a stricter TypeScript setup from day one, Nest also supports:
nest new my-first-nest-app --strictThe official docs note that --strict enables a stricter TypeScript compiler setup.
For beginners, using --strict is actually a pretty good habit.
It may complain more, but that is often TypeScript doing you a favor before production does the complaining for you.
Step 3: Move Into the Project Folder
Once the project is created:
cd my-first-nest-appNow you are inside your NestJS app.
This is the moment where everything feels new, slightly suspicious, and kind of exciting.
Step 4: Run the App
Start the project with:
npm run startOr during development, use watch mode:
npm run start:devFrom the CLI side, Nest also supports:
nest start
nest start --watchThe official CLI reference still lists nest start and --watch as the standard way to compile and run the app in watch mode.
Once the app starts, open:
http://localhost:3000You should see the default response:
Hello World!That comes from the starter controller and service that Nest generates for you.
If you see that message, congratulations.
Your first NestJS app is alive.
Step 5: Understand the Starter Project Structure
Now let’s look at the files Nest generated.
A new Nest project includes a src/ directory with these starter files:
app.controller.tsapp.controller.spec.tsapp.module.tsapp.service.tsmain.ts
Here is what they mean in normal human language.
main.ts
This is the entry point of your application.
It bootstraps the app using NestFactory and starts the HTTP server. The official starter code calls NestFactory.create(AppModule) and then app.listen(process.env.PORT ?? 3000).
Typical starter version:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();This file is basically saying:
“Hey Nest, take my root module, build the application, and start listening for requests.”
Simple. Important. Respect it.
app.module.ts
This is the root module.
Nest uses modules to organize your application.
At the beginning, AppModule is the top-level container that wires the basic parts together.
Think of it like the main room where the first pieces of your backend get registered.
app.controller.ts
This file handles incoming requests.
In the starter project, it usually contains a very simple route for / that returns the default response.
It is your first example of a controller in action.
app.service.ts
This file contains the business logic used by the controller.
In the starter app, it usually just returns the "Hello World!" string.
This separation is small now, but it teaches a very important Nest habit:
- controllers handle requests
- services handle logic
That habit becomes super useful when your app grows.
app.controller.spec.ts
This is a test file.
Even if you are not focused on testing yet, it is nice that Nest gives you a testing example immediately.
It is basically Nest saying:
“You may ignore this today, but your future self will be glad this exists.”
Step 6: Make Your First Tiny Change
Let’s do a small edit so the project feels like yours.
Open app.service.ts and change the returned text.
For example:
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Welcome to my first NestJS project!';
}
}Save the file.
If you are using watch mode, the app should reload automatically. The CLI docs still list watch mode for nest start --watch, and Nest’s standard starter scripts provide the same live development workflow.
Refresh http://localhost:3000
Now you should see your new message.
This is a tiny step, but it matters because it confirms:
- your app is running
- your code changes are applied
- the project is not just a template anymore
Now it is yours.
Step 7: Generate New Files with the CLI
One of the best parts of NestJS is that the CLI can generate common building blocks for you.
For example, you can create a module:
nest g module users
A controller:
nest g controller users
And a service:
nest g service users
The current CLI command reference still includes generators for module, controller, service, plus many others such as guard, pipe, interceptor, and resource.
This is one of those things that feels small at first, but later saves a lot of repetitive work.
Also, it helps keep your project structure consistent, which is one of the biggest reasons people enjoy working with Nest.
Step 8: Know the Difference Between src/, dist/, and test/
As your project grows, these folders matter.
src/
This is where your actual application source code lives.
You will spend most of your time here.
dist/
This is the compiled output folder after building the app.
You usually do not edit files here manually.
test/
This is where end-to-end or other test-related files can live, depending on your setup.
The Nest CLI docs explicitly note that nest new creates source code under /src and end-to-end tests under /test.
So the mental model is:
- write code in
src - generated build output goes to
dist - testing files live in
test
Easy enough.
Step 9: Add Environment Variables the Right Way
Sooner or later, you will want config values like:
- port
- database URL
- API keys
- environment mode
Nest’s current configuration docs recommend using .env files together with @nestjs/config, typically imported via ConfigModule.forRoot() in the root module.
Install it like this:
npm i --save @nestjs/configThen in app.module.ts:
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [ConfigModule.forRoot()],
})
export class AppModule {}By default, ConfigModule.forRoot() loads a .env file from the project root and merges it with runtime environment variables; if the same key exists in both places, the runtime environment value takes precedence.
Example .env file:
PORT=3000
APP_NAME=my-first-nest-app
This is not something you must fully master on day one.
But it is a good habit to know early.
Because “I hardcoded it for now” has a way of surviving much longer than it should.
Common Beginner Mistakes During Setup
Let’s save you from a few classic first-day problems.
1. Node version issues
If Nest or dependencies behave strangely, check your Node version first. Using an LTS version is the safest choice for real projects.
2. CLI not recognized
If nest is not found, the global CLI install may not have worked, or your npm global bin path is not available in your shell.
3. Wrong folder
This happens more than people admit.
You create the app, but run commands outside the project folder.
Then everything feels broken, but really the terminal is just in the wrong place.
A classic.
4. Port already in use
If port 3000 is busy, your app may fail to start. The starter bootstrap uses process.env.PORT ?? 3000, so setting PORT is the simplest way to switch.
5. Editing dist/ instead of src/
Never trust tired-you around compiled folders.
Write your code in src.
Always.
Why This Setup Step Actually Matters
It is easy to think setup is just the boring part you rush through before “real coding.”
But in NestJS, the starter project teaches you a lot right away:
- apps are organized around modules
- controllers and services are separated
- the app starts from a single bootstrap file
- the CLI is part of the normal workflow
- structure matters from day one
That is a big reason Nest feels different from loosely organized Node projects.
It nudges you toward clean architecture early.
And honestly, that is one of its best qualities.
Final Thoughts
Setting up your first NestJS project is not hard.
The main flow is really just:
- install Node.js
- install the Nest CLI
- create a project
- run it
- understand the generated structure
- make a tiny change
- start building
That is it.
Once you have done this once, Nest starts to feel much less intimidating.
And from here, the next step is the really important one:
understanding modules, controllers, and providers
Because that is where NestJS starts to truly make sense.
Now that your first NestJS project is running, the next question is the one that really matters:
What are all these files actually doing?
In the next article, we’ll break down the three core building blocks of a NestJS app — modules, controllers, and providers — so you can understand how everything fits together instead of just running code and hoping for the best.
FAQ
Do I need TypeScript to start a NestJS project?
No. Nest supports JavaScript too, and the CLI can generate a project with --language JS. But most Nest projects use TypeScript, and that is the default developer path.
What command creates a new NestJS app?
Use:
nest new my-first-nest-app
That is the standard project creation command in the official CLI docs.
What file starts the NestJS application?
main.ts is the entry file that bootstraps the app with NestFactory.
What port does NestJS use by default?
The default starter app listens on process.env.PORT ?? 3000, so it uses port 3000 unless PORT is set.
Should I learn the Nest CLI early?
Yes. It saves time, keeps your structure consistent, and is part of the normal Nest development workflow. The official CLI supports project creation, generators, builds, and watch-mode startup.