Understanding AppModule and Creating Your First Feature Module (Users)
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
AppModuledoes (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, andverify everything is wired correctly.
1) Why AppModule is the center of the app
Nest boots like this:
main.ts → AppModule → (your feature modules)
main.tscallsNestFactory.create(AppModule).AppModuleis 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.tsapp.controller.tsapp.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)
- Make the folder and module file:
src/users/users.module.ts
- 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 {}
- Wire it into
AppModuleso 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 {}
- 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)
- Preview the changes (safe mode):
nest g module users --dry-run
This typically shows:
create
src/users/users.module.tsupdate
src/app.module.ts(addsUsersModuletoimports)
- 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
AppModuleaway fromsrc/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 inapp.module.ts(relative paths are easy to mistype).UsersModule not in logs
EnsureUsersModuleis listed inimports: []of some module (usuallyAppModule).App fails after moving files
Fix theAppModulepath inmain.tsand restartnpm run start:dev.