# NestJS Module Best Practices for Clean Code Organization

[NestJS](https://blog.bytescrum.com/introduction-to-nestjs-a-beginners-guide) is a powerful framework for building server-side [applications](https://bytescrum.com/) using Node.js. It is built with TypeScript and offers an out-of-the-box application architecture that allows for the creation of highly testable, scalable, and maintainable applications. One of the core concepts in NestJS is **modules**. This guide will break down what modules are and how to use them in simple, human-readable language.

## What Are Modules?

In NestJS, a module is a class annotated with a `@Module()` decorator. Modules are used to organize the application's components, such as [controllers](https://blog.bytescrum.com/building-powerful-apis-with-nestjs-controllers), [providers](https://blog.bytescrum.com/nestjs-providers-the-core-building-blocks-of-dependency-injection), and services, into cohesive blocks of functionality. This modular structure makes it easier to manage and scale applications. Modules can be thought of as the building blocks of a NestJS application. Each module focuses on a specific feature or a set of related features.

Think of modules as different sections of a house—each room has its own purpose and contains related items.

## Why Use Modules?

Modules help keep your code organized and maintainable. By grouping related functionality together, you can easily manage and scale your application. For example, you might have separate modules for users, products, and orders in an e-commerce application.

## Creating a Module

Let's create a module called `UsersModule`. First, make sure you have NestJS CLI installed:

```bash
npm install -g @nestjs/cli
```

Next, create a new NestJS project:

```bash
nest new my-nest-app
cd my-nest-app
```

Generate a new module using the CLI:

```bash
nest generate module users
```

This command creates a `users` module with a file structure like this:

```plaintext
src/
  users/
    users.module.ts
```

Here’s a basic `UsersModule`:

```typescript
// users.module.ts
import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

@Module({
  controllers: [UsersController],
  providers: [UsersService],
})
export class UsersModule {}
```

### Understanding the `@Module()` Decorator

* **controllers**: This array lists the controllers that handle incoming requests and send responses. In this case, it includes `UsersController`.
    
* **providers**: This array lists the providers like services that handle the business logic. It includes `UsersService`.
    

## Creating a Controller

Controllers handle incoming requests and send responses to the client. Let's create a `UsersController`:

```bash
nest generate controller users
```

This generates a controller file:

```plaintext
src/
  users/
    users.controller.ts
```

Here’s a simple `UsersController`:

```typescript
// users.controller.ts
import { Controller, Get } from '@nestjs/common';
import { UsersService } from './users.service';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Get()
  findAll(): string {
    return this.usersService.findAll();
  }
}
```

* `@Controller('users')`: This decorator specifies that this controller handles requests to the `/users` route.
    
* `@Get()`: This decorator indicates that the `findAll` method handles GET requests to `/users`.
    
* `findAll()`: This method returns a string response.
    

## Creating a Service

Services handle the business logic. Let’s create a `UsersService`:

```bash
nest generate service users
```

This generates a service file:

```plaintext
src/
  users/
    users.service.ts
```

Here’s a simple `UsersService`:

```typescript
// users.service.ts
import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  findAll(): string {
    return 'This action returns all users';
  }
}
```

* `@Injectable()`: This decorator marks the class as a provider that can be injected into other classes.
    
* `findAll()`: This method contains the business logic to return a string response.
    

## Using the Module

Now that we have a module, a controller, and a service, let's put them together in the main application module. Open `app.module.ts`:

```typescript
// app.module.ts
import { Module } from '@nestjs/common';
import { UsersModule } from './users/users.module';

@Module({
  imports: [UsersModule],
})
export class AppModule {}
```

Here, `UsersModule` is imported and added to the `imports` array. This tells NestJS to include the `UsersModule` in the application.

## Advanced Module Concepts

### Module Re-Exporting

Modules can be re-exported to make their components available to other modules. For instance, if a `SharedModule` is created and it exports common services, this module can be imported and its components will be available to any module that imports the `SharedModule`.

```typescript
// shared.module.ts
import { Module } from '@nestjs/common';
import { CommonService } from './common.service';

@Module({
  providers: [CommonService],
  exports: [CommonService],
})
export class SharedModule {}
```

### Global Modules

Sometimes, certain services or components need to be available globally. This can be achieved by marking a module as global. A global module makes its components available across the entire application without needing to import the module in other modules.

```typescript
// common.module.ts
import { Global, Module } from '@nestjs/common';
import { CommonService } from './common.service';

@Global()
@Module({
  providers: [CommonService],
  exports: [CommonService],
})
export class CommonModule {}
```

### Dynamic Modules

Dynamic modules allow for a module to be configured dynamically. This can be useful for setting up modules that require configuration settings to be passed in at runtime.

```typescript
// database.module.ts
import { Module, DynamicModule } from '@nestjs/common';
import { DatabaseService } from './database.service';

@Module({})
export class DatabaseModule {
  static forRoot(config: DatabaseConfig): DynamicModule {
    return {
      module: DatabaseModule,
      providers: [
        {
          provide: 'DATABASE_CONFIG',
          useValue: config,
        },
        DatabaseService,
      ],
      exports: [DatabaseService],
    };
  }
}
```

---

<details data-node-type="hn-details-summary"><summary>Conclusion</summary><div data-type="detailsContent">Modules are a fundamental part of NestJS, helping to organize an application into manageable, scalable, and maintainable parts. By grouping related components together, modules make it easier to build complex applications with clear boundaries and dependencies.</div></details>

In this simple guide, the following points were covered:

* What modules are
    
* How to create a module
    
* How to create and use controllers and services within a module
    
* Advanced module concepts, including re-exporting, global modules, and dynamic modules
    

With these basics and advanced concepts, a robust application can be built using NestJS. Happy coding!
