Start Building a NestJS Application

Build a NestJS application from scratch.

Next, we’ll learn how to create a new NestJS project from scratch, set up the necessary dependencies, and create our first controller, service, and module. By the end of this lesson, we’ll gain a basic understanding of how NestJS combines the concepts of services, modules, and controllers to build web applications.

Project setup

To understand how different blocks work together in NestJS, let’s build our first NestJS application from scratch. To do this, we must install Node.js and npm. The advantage of using Educative is that we won’t need to install any additional dependencies. Everything runs in the browser. However, the following are the steps to create our project from scratch:

  1. Create a new folder named hello-world. Navigate to the newly created folder. Using your preferred command-line interface, execute the following commands:
mkdir hello-world
cd hello-world
npm init -y
  1. Install the required dependencies. In the terminal or command prompt, run the following command:
npm install --save @nestjs/common @nestjs/core @nestjs/platform-express reflect-metadata
  1. Install the development dependencies. Use the terminal or command prompt and run the following command:
npm install --save-dev @types/node ts-node-dev typescript
  1. Create an entry file named main.ts within the hello-world folder.

  2. Create a TypeScript configuration file named tsconfig.json in the hello-world folder. Use this file to specify your application TypeScript compiler options.

After following these steps, our project structure should resemble the following:

├── main.ts
├── node_modules/
│   ├── ... (dependencies)
├── package.json
├── package-lock.json
├── tsconfig.json

TypeScript configuration

The TypeScript configuration file, which is named tsconfig.json, specifies various compiler options for compiling TypeScript code. In the context of NestJS, the TypeScript configuration file specifies compiler options specific to the NestJS framework.

Press + to interact
"compilerOptions": {
"module": "commonjs",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "ES2017"

The module option determines what module format the TypeScript compiler uses to output the compiled JavaScript code. CommonJS is a popular module format used in Node.js applications.

The emitDecoratorMetadata and experimentalDecorators options enable support for decorators in TypeScript code. Decorators are a feature in TypeScript and JavaScript that allow modification or add functionality to classes, methods, and properties at runtime.

Finally, the target option specifies which version of ECMAScript the TypeScript compiler should compile the code to.

Update the entry file

Let’s explore how modules, controllers, and services work together as the core components of a NestJS application, facilitating code organization and structure. To begin, let’s update our main.ts file with the following changes:

import { Controller, Get, Injectable, Module } from "@nestjs/common";
import { NestFactory } from "@nestjs/core";

// Service
export class AppService {
  sayHello() {
    return 'Hello World';

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

  sayHello() {
    return this.appService.sayHello();

// Module
  controllers: [AppController],
  providers: [AppService]
export class AppModule {}

// Bootstrap the application
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);

A hello world NestJS application

Note: Some important buttons from the code above are listed below:

  • Save button: This button in the widget is designed to preserve any modifications you make. So when you return to a lesson, you’ll see your personalized code exactly as you left it instead of the default code we provide.

  • Reset button: The “Reset” button helps revert all your changes to the original code we provide.

Press the “Run” button to start the application.

Here are the key things to notice about our application:

  • The @Controller() decorator defines the AppController class as a controller. Controllers handle incoming HTTP requests and return responses to the client.

  • The @Injectable() decorator defines the AppService class as a provider, and AppController can inject it as a dependency.

  • The @Get() decorator defines a route for the sayHello() method of AppController, which handles incoming GET requests to the root route /. Upon receiving the request, AppController calls the sayHello() method and returns its result as the response to the client.

  • The AppService class contains a single method called sayHello() that returns a string message.

  • The @Module() decorator defines the AppModule class as a module. Modules organize and group related controllers and services.

  • The controllers property of the @Module() decorator specifies which controllers belong to the AppModule. Here, we define AppController as the controller.

  • The @Module() decorator specifies which services belong to the AppModule by listing them in the providers property. In this case, we include the AppService class as the service.

  • The bootstrap() function creates an instance of the NestJS application by passing in the AppModule class, enabling the application to handle incoming HTTP requests. Afterward, it calls the listen() method to start the application and listen for incoming HTTP requests on port 3000.