NestJS Folder Structure Explained for Beginners
When you run nest new for the first time, the Nest CLI generates a project with several files and folders you have never seen before if you are coming from plain Express. Understanding what each of these does immediately is essential, because every NestJS project you ever open, whether a tutorial repo or a company's production codebase, will follow this same base structure.
This lesson walks through the generated project folder by folder and file by file, explaining the purpose of each piece and how they connect to form a running application.
NestJS Folder Structure: Learning Objectives
- Identify the purpose of every default file and folder generated by the Nest CLI.
- Explain the role of main.ts as the application's entry point.
- Understand the relationship between app.module.ts, app.controller.ts, and app.service.ts.
- Recognize how the src, test, and dist folders differ in purpose.
- Apply a consistent folder convention when adding new features to a NestJS project.
NestJS Folder Structure: Key Terms and Definitions
- src folder: The main source directory containing all of your application's TypeScript code.
- main.ts: The entry point file that bootstraps and starts the NestJS application.
- app.module.ts: The root module of the application, which registers all other modules, controllers, and providers.
- dist folder: The output directory containing compiled JavaScript generated from your TypeScript source, used in production.
- test folder: A directory containing end-to-end (e2e) test files, separate from unit tests which usually live beside their source files.
- tsconfig.json: The TypeScript compiler configuration file defining how .ts files are compiled into JavaScript.
How NestJS Folder Structure Works: Detailed Explanation
At the root of a freshly generated NestJS project, you will find configuration files like package.json, tsconfig.json, nest-cli.json, and .eslintrc.js, alongside two main folders: src and test.
The src folder is where almost all of your work happens. Inside it, main.ts is the very first file that runs when your application starts. It imports the NestFactory utility, uses it to create an application instance from your root module, and calls app.listen() to start the HTTP server on a specified port. Think of main.ts as the ignition switch for your entire application.
Right next to main.ts sits app.module.ts, the root module. Every NestJS application has exactly one root module, decorated with @Module(), which acts as the top-level container referencing all the feature modules, controllers, and providers your application needs. As your app grows, you will create additional modules for each feature (a UsersModule, an OrdersModule, and so on), and each of these gets imported into app.module.ts or into each other, forming a tree of modules.
The starter project also includes app.controller.ts and app.service.ts as working examples of a controller and a provider. The controller defines a route (a GET request to the root path) and the service contains the actual logic that route calls. This pairing demonstrates the Controller-Service pattern you will replicate for every feature you build throughout this course.
Outside of src, the test folder contains end-to-end test files (typically named app.e2e-spec.ts), which test your application's behavior from the outside, simulating real HTTP requests. Unit test files, by contrast, are usually placed directly next to the file they test inside src, following the naming convention filename.spec.ts.
Finally, when you build your project for production using npm run build, NestJS compiles all TypeScript files in src into plain JavaScript and places the output in a dist folder. This dist folder, not src, is what actually runs in a production environment using node dist/main.js.
Interview-Friendly Explanation
A strong interview or viva answer for nestjs folder structure must go beyond a one-line definition. Interviewers evaluating BCA, MCA, B.Tech, and self-taught backend developers reward answers that combine a precise definition, a clear working explanation, a real-world example, and a conclusion that highlights why it matters in production Node.js applications. Use the four-point framework below when answering under time pressure.
- Definition point: src folder: The main source directory containing all of your application's TypeScript code.
- Working point: Explain the role of main.ts as the application's entry point.
- Example point: Enterprise NestJS codebases extend this same base structure by adding a src/modules folder, with each feature (auth, users, orders) as its own subfolder containing its own controller, service, module, and DTOs.
- Conclusion point: Every NestJS project, regardless of size, starts from this same predictable base structure generated by the Nest CLI.
How to Answer This in a Technical Interview
- Give a two-to-three sentence definition using correct NestJS and Node.js terminology.
- Add one specific example drawn from a real backend scenario such as an e-commerce, fintech, or SaaS API.
- Mention how it compares to plain Express.js if relevant, since interviewers often probe this contrast.
- Close with one benefit, trade-off, or production use case.
- Avoid vague answers like "it just works" — interviewers filter these out immediately.
Practical Scenario
Imagine you are building a production backend for a SaaS product, similar to systems used at companies like Swiggy, Razorpay, or Freshworks. Every lesson in this NestJS course maps directly to a decision you will make while building that backend: how you structure code, how you separate concerns, how you test it, and how you scale it under real traffic.
NestJS Folder Structure: Architecture and Flow Diagram
Visualize a folder tree:
my-first-nestjs-app/
├── src/
│ ├── main.ts (application entry point)
│ ├── app.module.ts (root module)
│ ├── app.controller.ts (handles routes)
│ ├── app.service.ts (business logic)
│ ├── app.controller.spec.ts (unit test)
├── test/
│ └── app.e2e-spec.ts (end-to-end test)
├── dist/ (compiled JS output, created after build)
├── package.json
├── tsconfig.json
└── nest-cli.json
NestJS Folder Structure: File / Folder Reference Table
| File / Folder | Purpose |
|---|---|
| main.ts | Bootstraps the application and starts the HTTP server |
| app.module.ts | The root module registering controllers and providers |
| app.controller.ts | Defines routes and delegates logic to services |
| app.service.ts | Contains business logic, injected into controllers |
| test/ folder | Holds end-to-end (e2e) test files |
| dist/ folder | Compiled JavaScript output used in production, generated by npm run build |
| nest-cli.json | Configuration for the Nest CLI itself, such as source root and compiler options |
NestJS Folder Structure: NestJS Code Example
// src/main.ts — the application entry point
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
console.log('Application is running on: http://localhost:3000');
}
bootstrap();
// src/app.module.ts — the root module
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [], // other feature modules go here
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
main.ts uses NestFactory.create(AppModule) to build the entire application from the root module, then starts listening on port 3000. Notice that main.ts never directly references AppController or AppService — it only knows about AppModule. This is intentional: the module is responsible for wiring its own controllers and providers together, keeping main.ts extremely thin and focused purely on bootstrapping.
Real-World NestJS Folder Structure Industry Examples
- Enterprise NestJS codebases extend this same base structure by adding a src/modules folder, with each feature (auth, users, orders) as its own subfolder containing its own controller, service, module, and DTOs.
- DevOps teams configure Docker build steps around the dist folder specifically, since only the compiled JavaScript output needs to be shipped to production, not the raw TypeScript source.
- Code review guidelines at many companies require new features to mirror the app.controller.ts / app.service.ts pattern exactly, so reviewers can predict where to find routing versus business logic.
- CI pipelines commonly run tests from the test/ folder as a final gate before deployment, since e2e tests validate real HTTP behavior rather than isolated units.
NestJS Folder Structure Interview Questions and Answers
Q1. What is the role of main.ts in a NestJS application?
Short answer: main.ts is the entry point of a NestJS application. It uses NestFactory.create() to instantiate the application from the root module and calls app.listen() to start the HTTP server on a given port, effectively bootstrapping the entire app.
Detailed explanation: At the root of a freshly generated NestJS project, you will find configuration files like package.json, tsconfig.json, nest-cli.json, and .eslintrc.js, alongside two main folders: src and test. The src folder is where almost all of your work happens. Inside it, main.ts is the very first file that runs when your application starts. It imports the NestFactory utility, uses it to create an application instance from your root module, and calls app.listen() to start the HTTP server on a specified port. Think of main.ts as the ignition switch for your entire application. Right next to main.ts sits app.module.ts, the root module. Every NestJS application has exactly one root module, decorated with @Module(), which acts as the top-level container referencing all the feature modules, controllers, and providers your application needs. As your app grows, you will create additional modules for each feature (a UsersModule, an OrdersModule, and so on), and each of these gets imported into app.module.ts or into each other, forming a tree of modules. The starter project also includes app.controller.ts and app.service.ts as working examples of a controller and a provider. The controller defines a route (a GET request to the root path) and the service contains the actual logic that route calls. This pairing demonstrates the Controller-Service pattern you will replicate for every feature you build throughout this course. Outside of src, the test folder contains end-to-end test files (typically named app.e2e-spec.ts), which test your application's behavior from the outside, simulating real HTTP requests. Unit test files, by contrast, are usually placed directly next to the file they test inside src, following the naming convention filename.spec.ts. Finally, when you build your project for production using npm run build, NestJS compiles all TypeScript files in src into plain JavaScript and places the output in a dist folder. This dist folder, not src, is what actually runs in a production environment using node dist/main.js.
Practical example: Enterprise NestJS codebases extend this same base structure by adding a src/modules folder, with each feature (auth, users, orders) as its own subfolder containing its own controller, service, module, and DTOs.
Interview tip: main.ts bootstraps the app using NestFactory.create(AppModule) and app.listen(port).
Revision hook: Every NestJS project, regardless of size, starts from this same predictable base structure generated by the Nest CLI.
Q2. What is the root module in NestJS and why is it important?
Short answer: The root module, typically named AppModule and defined in app.module.ts, is the top-level module that NestJS uses to build the application's dependency graph. It imports all other feature modules and registers the top-level controllers and providers.
Detailed explanation: main.ts uses NestFactory.create(AppModule) to build the entire application from the root module, then starts listening on port 3000. Notice that main.ts never directly references AppController or AppService — it only knows about AppModule. This is intentional: the module is responsible for wiring its own controllers and providers together, keeping main.ts extremely thin and focused purely on bootstrapping.
Practical example: DevOps teams configure Docker build steps around the dist folder specifically, since only the compiled JavaScript output needs to be shipped to production, not the raw TypeScript source.
Interview tip: app.module.ts is the root module; every controller and provider must eventually be registered in some module's decorator.
Revision hook: main.ts should remain thin — its only job is to bootstrap the application from the root module.
Q3. What is the difference between the src and dist folders?
Short answer: The src folder contains your original TypeScript source code that you write and edit. The dist folder contains compiled, plain JavaScript output generated by the TypeScript compiler when you run npm run build, and it is this compiled output that actually runs in production.
Detailed explanation: A default NestJS project generated by the Nest CLI includes a src folder holding your TypeScript source code, a test folder for end-to-end tests, and configuration files like package.json and tsconfig.json. Inside src, main.ts bootstraps the application from the root module defined in app.module.ts, which registers the starter app.controller.ts and app.service.ts as an example of the Controller-Service pattern. Running npm run build compiles everything into a dist folder, which is what actually runs in production. Understanding this structure early makes every future NestJS project, tutorial, or company codebase immediately familiar.
Practical example: Code review guidelines at many companies require new features to mirror the app.controller.ts / app.service.ts pattern exactly, so reviewers can predict where to find routing versus business logic.
Interview tip: src holds source TypeScript; dist holds compiled JavaScript output after npm run build.
Revision hook: The Controller-Service pairing shown in app.controller.ts and app.service.ts is the pattern you will repeat for every new feature.
Q4. Where do end-to-end tests live in a NestJS project, and how do they differ from unit tests?
Short answer: End-to-end tests live in the separate test folder, typically as files ending in .e2e-spec.ts, and they test the application's behavior via real HTTP requests. Unit tests, ending in .spec.ts, usually sit next to the file they test inside src and test individual classes in isolation.
Detailed explanation: At the root of a freshly generated NestJS project, you will find configuration files like package.json, tsconfig.json, nest-cli.json, and .eslintrc.js, alongside two main folders: src and test. The src folder is where almost all of your work happens. Inside it, main.ts is the very first file that runs when your application starts. It imports the NestFactory utility, uses it to create an application instance from your root module, and calls app.listen() to start the HTTP server on a specified port. Think of main.ts as the ignition switch for your entire application. Right next to main.ts sits app.module.ts, the root module. Every NestJS application has exactly one root module, decorated with @Module(), which acts as the top-level container referencing all the feature modules, controllers, and providers your application needs. As your app grows, you will create additional modules for each feature (a UsersModule, an OrdersModule, and so on), and each of these gets imported into app.module.ts or into each other, forming a tree of modules. The starter project also includes app.controller.ts and app.service.ts as working examples of a controller and a provider. The controller defines a route (a GET request to the root path) and the service contains the actual logic that route calls. This pairing demonstrates the Controller-Service pattern you will replicate for every feature you build throughout this course. Outside of src, the test folder contains end-to-end test files (typically named app.e2e-spec.ts), which test your application's behavior from the outside, simulating real HTTP requests. Unit test files, by contrast, are usually placed directly next to the file they test inside src, following the naming convention filename.spec.ts. Finally, when you build your project for production using npm run build, NestJS compiles all TypeScript files in src into plain JavaScript and places the output in a dist folder. This dist folder, not src, is what actually runs in a production environment using node dist/main.js.
Practical example: CI pipelines commonly run tests from the test/ folder as a final gate before deployment, since e2e tests validate real HTTP behavior rather than isolated units.
Interview tip: test/ folder holds e2e tests; unit test files (.spec.ts) live alongside their source files inside src.
Revision hook: Understanding src vs dist prevents confusing production debugging sessions later in your career.
NestJS Folder Structure MCQs and Practice Questions
1. Which file is the entry point of a NestJS application?
- app.module.ts
- main.ts
- app.controller.ts
- package.json
Answer: B. main.ts
Explanation: main.ts bootstraps the application using NestFactory.create() and starts the HTTP server, making it the true starting point of execution.
Concept link: main.ts bootstraps the app using NestFactory.create(AppModule) and app.listen(port).
Why this matters: Every NestJS project, regardless of size, starts from this same predictable base structure generated by the Nest CLI.
2. What does the @Module() decorator in app.module.ts do?
- Starts the HTTP server
- Registers controllers, providers, and imported modules
- Compiles TypeScript to JavaScript
- Defines a single HTTP route
Answer: B. Registers controllers, providers, and imported modules
Explanation: The @Module() decorator attaches metadata to a class describing which controllers, providers, and other modules belong to it, which NestJS uses to build the dependency injection graph.
Concept link: app.module.ts is the root module; every controller and provider must eventually be registered in some module's decorator.
Why this matters: main.ts should remain thin — its only job is to bootstrap the application from the root module.
3. Where does compiled JavaScript output go after running npm run build?
- src folder
- test folder
- dist folder
- node_modules folder
Answer: C. dist folder
Explanation: The TypeScript compiler outputs plain JavaScript files into the dist folder, which is what actually gets executed in a production environment.
Concept link: src holds source TypeScript; dist holds compiled JavaScript output after npm run build.
Why this matters: The Controller-Service pairing shown in app.controller.ts and app.service.ts is the pattern you will repeat for every new feature.
4. What is the typical file naming convention for end-to-end tests in NestJS?
- filename.test.ts
- filename.e2e-spec.ts
- filename.unit.ts
- filename.e2e.js
Answer: B. filename.e2e-spec.ts
Explanation: NestJS convention places e2e tests in the test folder with the .e2e-spec.ts suffix, distinguishing them from unit test files that use the .spec.ts suffix.
Concept link: test/ folder holds e2e tests; unit test files (.spec.ts) live alongside their source files inside src.
Why this matters: Understanding src vs dist prevents confusing production debugging sessions later in your career.
Common NestJS Folder Structure Mistakes to Avoid
- Editing files inside the dist folder directly, not realizing they get completely overwritten every time you rebuild the project.
- Assuming main.ts contains business logic; it should stay minimal and only handle application bootstrapping.
- Forgetting to register a newly created controller or provider inside the relevant module's @Module() decorator, causing dependency injection errors.
- Mixing unit test and e2e test conventions, placing e2e-style tests inside src instead of the dedicated test folder.
NestJS Folder Structure: Interview Notes and Exam Tips
- main.ts bootstraps the app using NestFactory.create(AppModule) and app.listen(port).
- app.module.ts is the root module; every controller and provider must eventually be registered in some module's decorator.
- src holds source TypeScript; dist holds compiled JavaScript output after npm run build.
- test/ folder holds e2e tests; unit test files (.spec.ts) live alongside their source files inside src.
Key NestJS Folder Structure Takeaways
- Every NestJS project, regardless of size, starts from this same predictable base structure generated by the Nest CLI.
- main.ts should remain thin — its only job is to bootstrap the application from the root module.
- The Controller-Service pairing shown in app.controller.ts and app.service.ts is the pattern you will repeat for every new feature.
- Understanding src vs dist prevents confusing production debugging sessions later in your career.
NestJS Folder Structure: Summary
A default NestJS project generated by the Nest CLI includes a src folder holding your TypeScript source code, a test folder for end-to-end tests, and configuration files like package.json and tsconfig.json. Inside src, main.ts bootstraps the application from the root module defined in app.module.ts, which registers the starter app.controller.ts and app.service.ts as an example of the Controller-Service pattern. Running npm run build compiles everything into a dist folder, which is what actually runs in production. Understanding this structure early makes every future NestJS project, tutorial, or company codebase immediately familiar.