NestJS Project Structure

Every NestJS project starts with a standard folder layout. Understanding this layout lets you navigate any NestJS codebase quickly, whether you created it or joined an existing team. This topic breaks down each file and folder so nothing is a mystery.

The Top-Level Structure

When you run nest new my-app, the CLI creates this structure:

my-app/
├── src/                  ← Your application code lives here
│   ├── app.controller.ts
│   ├── app.controller.spec.ts
│   ├── app.module.ts
│   ├── app.service.ts
│   └── main.ts
├── test/                 ← End-to-end test files
│   ├── app.e2e-spec.ts
│   └── jest-e2e.json
├── node_modules/         ← Installed npm packages (auto-generated)
├── .eslintrc.js          ← Code style rules
├── .prettierrc           ← Code formatting rules
├── nest-cli.json         ← NestJS CLI configuration
├── package.json          ← Project info and scripts
├── tsconfig.json         ← TypeScript configuration
└── tsconfig.build.json   ← TypeScript config for production build

The src Folder — Your Workspace

Everything you write goes inside the src folder. Each file has a specific role:

main.ts — The Entry Point

This is the first file NestJS reads. It creates the application and starts listening for HTTP requests on a port (3000 by default).

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

Think of main.ts as the "on" button for your application. It boots everything up.

app.module.ts — The Root Module

Every NestJS application has exactly one root module. All other modules register here. It is the central hub that connects every feature in your application.

app.controller.ts — The First Controller

Controllers handle incoming HTTP requests. The starter controller maps the root URL (/) to the getHello() method, which returns "Hello World!".

app.service.ts — The First Service

Services contain business logic. The starter service has a getHello() method that returns a string. The controller calls this service method instead of containing the logic itself.

app.controller.spec.ts — Unit Tests

Every controller and service gets a matching .spec.ts file. This is the test file where you write unit tests for that component. The CLI generates it automatically.

How Files Work Together

Here is a diagram showing how a request travels through the starter project:

HTTP GET /
     |
     v
app.controller.ts
  @Get() getHello()
     |
     v
app.service.ts
  getHello() → returns "Hello World!"
     |
     v
Response: "Hello World!"

The controller receives the request. The service does the work. The controller sends the result back. This pattern repeats across every feature you build.

Growing the Structure

As your application adds features, new folders appear inside src. A well-organized NestJS project looks like this:

src/
├── users/
│   ├── users.module.ts
│   ├── users.controller.ts
│   ├── users.service.ts
│   └── dto/
│       ├── create-user.dto.ts
│       └── update-user.dto.ts
├── products/
│   ├── products.module.ts
│   ├── products.controller.ts
│   └── products.service.ts
├── auth/
│   ├── auth.module.ts
│   ├── auth.controller.ts
│   └── auth.service.ts
├── app.module.ts
└── main.ts

Each feature (users, products, auth) lives in its own folder. Each folder contains a module, a controller, and a service — the three core building blocks of NestJS.

Configuration Files Explained

package.json

Lists all project dependencies and the scripts you run with npm run. The most used scripts are start:dev for development and build for production.

tsconfig.json

Configures how TypeScript compiles your code. NestJS sets sensible defaults here. You rarely need to change it unless you add advanced TypeScript features.

nest-cli.json

Tells the NestJS CLI where your source files live and how to build the project. The default settings work for almost all projects.

.eslintrc.js and .prettierrc

These enforce consistent code style across your project. ESLint catches potential bugs and anti-patterns. Prettier formats your code automatically. Both save time during code reviews.

The node_modules Folder

This folder contains all the npm packages your project depends on. It is auto-generated when you run npm install and can be deleted and recreated at any time. Never commit this folder to version control — your .gitignore file already excludes it.

With this structure in mind, you always know exactly where to find or place any piece of code. Features sit in their own folders. Tests live beside the files they test. Configuration stays at the root. The layout scales cleanly from a one-page project to a hundred-module enterprise application.

Leave a Comment

Your email address will not be published. Required fields are marked *