Skip to main content

Command Palette

Search for a command to run...

Understanding AppModule and Creating Your First Feature Module (Users)

Published
3 min read
M

As a former 3D Animator with more than 12 years of experience, I have always been fascinated by the intersection of technology and creativity. That's why I recently shifted my career towards MERN stack development and software engineering, where I have been serving since 2021.

With my background in 3D animation, I bring a unique perspective to software development, combining creativity and technical expertise to build innovative and visually engaging applications. I have a passion for learning and staying up-to-date with the latest technologies and best practices, and I enjoy collaborating with cross-functional teams to solve complex problems and create seamless user experiences.

In my current role as a MERN stack developer, I have been responsible for developing and implementing web applications using MongoDB, Express, React, and Node.js. I have also gained experience in Agile development methodologies, version control with Git, and cloud-based deployment using platforms like Heroku and AWS.

I am committed to delivering high-quality work that meets the needs of both clients and end-users, and I am always seeking new challenges and opportunities to grow both personally and professionally.

In the previous lesson we saw how main.ts bootstraps the app. It creates the Nest application from a single root module: AppModule. In this post we’ll:

  • clarify what AppModule does (and why it matters),

  • demystify file naming vs. decorators,

  • show how to reorganize files safely,

  • create a real feature module (Users) both manually and with the Nest CLI, and

  • verify everything is wired correctly.


1) Why AppModule is the center of the app

Nest boots like this:

main.ts  →  AppModule  →  (your feature modules)
  • main.ts calls NestFactory.create(AppModule).

  • AppModule is the root wiring hub. Any feature you build must be imported here (directly or indirectly) to become part of the app graph.

A minimal AppModule:

// src/app.module.ts
import { Module } from '@nestjs/common';

@Module({
  imports: [],        // add feature modules here
  controllers: [],    // app-level controllers (optional)
  providers: [],      // app-level providers (optional)
})
export class AppModule {}

2) Naming conventions vs. decorators (important!)

You’ll see files like:

  • app.module.ts, users.module.ts

  • app.controller.ts

  • app.controller.spec.ts

These names are for humans. What actually gives behavior are the decorators:

  • @Module() → makes a class a module

  • @Controller() → makes a class a controller

  • *.spec.ts → just a testing convention (picked up by test runners)

So a file called users.module.ts is not a module until the class inside is decorated with @Module().


3) Reorganizing app files (optional but common)

By default, the CLI places app files directly under src/. Many teams move them under src/app/:

src/
  app/
    app.module.ts
    app.controller.ts
    app.service.ts
  main.ts

If you do this, update main.ts so it points to the new path:

// src/main.ts
import { AppModule } from './app/app.module';

If the import is wrong, Nest will fail to start—fix the path and you’re good.


4) Create the Users feature module

Option A — Create it manually (great to learn the fundamentals)

  1. Make the folder and module file:
src/users/users.module.ts
  1. Turn the class into a Nest module:
// src/users/users.module.ts
import { Module } from '@nestjs/common';

@Module({
  // we'll add controllers/providers later
})
export class UsersModule {}
  1. Wire it into AppModule so the app knows it exists:
// src/app.module.ts
import { Module } from '@nestjs/common';
import { UsersModule } from './users/users.module';

@Module({
  imports: [UsersModule],
})
export class AppModule {}
  1. Run and verify:
npm run start:dev

You should see a log line similar to:

[InstanceLoader] UsersModule dependencies initialized

If you don’t, the module likely isn’t imported in AppModule.


Option B — Use the Nest CLI (fast for daily work)

  1. Preview the changes (safe mode):
nest g module users --dry-run

This typically shows:

  • create src/users/users.module.ts

  • update src/app.module.ts (adds UsersModule to imports)

  1. Generate for real:
nest g module users

Open src/users/users.module.ts (should match the manual version) and src/app.module.ts (CLI auto-added the import and entry in imports).

Note: If you moved AppModule away from src/app.module.ts, the CLI may not auto-update it. In that case, just add the import manually.


5) A quick look at the default app files

  • app.controller.ts — defines routes (e.g., GET /).

  • app.service.ts — holds the logic used by the controller (e.g., returns "Hello World!").

  • app.controller.spec.ts — unit tests for the controller (naming convention only).

Right now it may feel like “a lot of files for ‘Hello World!’”, but this structure pays off as your app grows: controllers handle I/O, services handle business logic, and modules group everything cleanly.


6) Troubleshooting

  • “Cannot find module './users/users.module'”
    Check the import path in app.module.ts (relative paths are easy to mistype).

  • UsersModule not in logs
    Ensure UsersModule is listed in imports: [] of some module (usually AppModule).

  • App fails after moving files
    Fix the AppModule path in main.ts and restart npm run start:dev.