Skip to main content

Command Palette

Search for a command to run...

Understanding Default NestJS Project Structure

Updated
•3 min read•View as Markdown
Understanding Default NestJS Project Structure
H

hasabTech is a developer-focused educational platform committed to simplifying tech learning. We share practical coding tutorials, programming guides, and tech insights to help beginners and aspiring developers build real world skills. Our mission is to make technical education accessible, clear, and community driven. We are currently building our in house products, experimenting with real world tech solutions, and sharing what we learn along the way.

In previous blog, we understood the use-cases for Node.js, Express.js and NestJS and then learned how to install NestJS CLI and initiated our project.

In this blog, we will understand default NestJS project structure.

We will not be diving deep into any of the configuration files; rather, we'd discuss core files which we will be using for our NestJS series.

Starting the project

In package.json file, you can find these two:

"start": "nest start",
"start:dev": "nest start --watch",

If you use npm run start then whenever you make changes, you will have to restart your server. So, during development mode, always run this: npm run start:dev so that as soon as you make any changes in the file, the server restarts automatically.

Nest.js Default Core Files

When diving into a NestJS project, the src/ directory plays host to several essential files. Let's take a closer look at each one:

main.ts:

As the gateway to your application, main.ts is where the NestJS application instance comes to life and is registered to a specific port (i.e., 3000 by default), enabling access from your client apps:

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

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

app.module.ts:

This file takes center stage as the root module for your application. Every other module you create will find its registration within this file:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

app.controller.ts:

This file serves as the foundation for your controllers, featuring a basic controller class with a single route definition.

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

app.controller.spec.ts:

This is the unit test file designed for the app.controller.ts class. It ensures the reliability of your controller through testing. Here's a snippet illustrating a basic test:

import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';

describe('AppController', () => {
  let appController: AppController;

  beforeEach(async () => {
    const app: TestingModule = await Test.createTestingModule({
      controllers: [AppController],
      providers: [AppService],
    }).compile();

    appController = app.get<AppController>(AppController);
  });

  describe('root', () => {
    it('should return "Hello World!"', () => {
      expect(appController.getHello()).toBe('Hello World!');
    });
  });
});

app.service.ts:

Here, you'll encounter a fundamental service responsible for executing logic utilized by your controller:

import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello Shameel!';
  }
}

Understanding the purpose of each core file empowers you to navigate and structure your NestJS project effectively.

If you’re a visual learner, check out the following video tutorial for this blog:

https://www.youtube.com/watch?v=3q06vqkSI_A&list=PLgKb0PcT0J0SaWTrS4ZY8ATMaqLeSXgM7&index=2

Follow us for more such content:

https://www.linkedin.com/company/hasabtech

https://www.youtube.com/@hasabTech

https://www.instagram.com/hasab.tech/

https://www.facebook.com/hasabTech

NestJS Tutorial

Part 2 of 3

Learn to build scalable backend apps using NestJS a modern Node.js framework with TypeScript. This series covers controllers, services, modules, dependency injection, routing, middleware, and database basics.

Up next

How to Create and Use Global Modules in NestJS

Recap from Previous Blog In our previous blog, we learned that when working inside the CatsModule, if we want to use a provider (dependency) in another module, the standard approach is to export it from cats.module.ts and then import it into the targ...

More from this blog

HasabTech

13 posts

HasabTech is a learning focused blog sharing practical tutorials, coding guides, and developer insights to help you grow your skills and build real-world software projects.