9 min readUpdated May 24, 2025

How to Inject a NestJS Service from Another Module: A Step-by-Step Guide

Struggling to inject a service from another module in your NestJS app? This guide simplifies the process, solving errors like Nest can't resolve dependencies. Learn how to export a service (e.g., UsersService), import its module into another (like AuthModule), and inject it seamlessly for modular, scalable applications. Follow clear steps and avoid pitfalls like missing exports or circular dependencies to keep your project running smoothly.

Written by

TypeScriptNestJSBackend DevelopmentReact, Vue and Typescript

How to Inject a NestJS Service from Another Module: A Step-by-Step Guide

If you’re building a modular NestJS application and need to use a service from one module in another, you might run into issues like Nest can't resolve dependencies of the <ServiceName>. This is a common challenge when working with NestJS’s module system, as modules are isolated by default. In this post, I’ll guide you through injecting a service from another module, based on insights from the community Stack Overflow, with clear steps and examples to keep your project running smoothly.

Why Inject a Service from Another Module?

NestJS encourages a modular architecture, where related functionality (e.g., controllers, services, and providers) is grouped into modules. For example, a UsersModule might handle user-related logic, while an AuthModule handles authentication. If the AuthService needs to check user credentials using the UsersService, you’ll need to inject UsersService into AuthModule. This requires proper module configuration to make the service accessible.

Understanding NestJS Modules and Dependency Injection

NestJS uses dependency injection (DI) to provide services to components. By default, a service is only available within its own module unless explicitly exported. To inject a service from another module:

  1. Export the service from its module.
  2. Import the module into the target module.
  3. Inject the service into the desired component (e.g., a controller or another service).

Let’s walk through how to set this up with a practical example.

Step-by-Step Solution

Imagine you have a UsersModule with a UsersService and an AuthModule that needs to use UsersService. Here’s how to make it work.

1. Create the UsersModule and UsersService

First, define the UsersService in users/users.service.ts:

1import { Injectable } from '@nestjs/common'; 2 3@Injectable() 4export class UsersService { 5 findUserById(id: number) { 6 return { id, name: 'John Doe' }; // Mock data for example 7 } 8}

Then, set up the UsersModule in users/users.module.ts, ensuring the UsersService is exported:

1import { Module } from '@nestjs/common'; 2import { UsersService } from './users.service'; 3 4@Module({ 5 providers: [UsersService], 6 exports: [UsersService], // Export the service to make it available to other modules 7}) 8export class UsersModule {}

The exports array tells NestJS that UsersService can be used by other modules that import UsersModule.

2. Import UsersModule into AuthModule

In auth/auth.module.ts, import the UsersModule to make UsersService available:

1import { Module } from '@nestjs/common'; 2import { AuthService } from './auth.service'; 3import { UsersModule } from '../users/users.module'; 4 5@Module({ 6 imports: [UsersModule], // Import the module that exports UsersService 7 providers: [AuthService], 8}) 9export class AuthModule {}

The imports array allows AuthModule to access the exported providers of UsersModule.

3. Inject UsersService into AuthService

Now, inject UsersService into AuthService in auth/auth.service.ts:

1import { Injectable } from '@nestjs/common'; 2import { UsersService } from '../users/users.service'; 3 4@Injectable() 5export class AuthService { 6 constructor(private readonly usersService: UsersService) {} 7 8 login(userId: number) { 9 const user = this.usersService.findUserById(userId); 10 return `Logged in user: ${user.name}`; 11 } 12}

The UsersService is injected via the constructor, and NestJS’s DI system resolves it because UsersModule is imported into AuthModule.

4. Test Your Setup

Create a controller in AuthModule to test the setup (auth/auth.controller.ts):

1import { Controller, Get, Param } from '@nestjs/common'; 2import { AuthService } from './auth.service'; 3 4@Controller('auth') 5export class AuthController { 6 constructor(private readonly authService: AuthService) {} 7 8 @Get('login/:id') 9 login(@Param('id') id: string) { 10 return this.authService.login(Number(id)); 11 } 12}

Run your application with npm run start:dev and test the endpoint (e.g., GET /auth/login/1). You should see the response Logged in user: John Doe.

Common Pitfalls and How to Avoid Them

Here are some mistakes that can cause issues when injecting services across modules:

  • Forgetting to Export the Service: If UsersService isn’t in the exports array of UsersModule, you’ll get a dependency resolution error. Always double-check the exports array.
  • Circular Dependencies: If UsersModule and AuthModule import each other, NestJS will throw a circular dependency error. Use forward references (forwardRef(() => OtherModule)) or refactor to a shared module.
  • Incorrect Module Imports: Ensure the module containing the service is imported into the target module’s imports array.
  • Scope Mismatch: If the service is scoped (e.g., REQUEST scope), ensure the injecting component supports the same scope.

Best Practices for Modular NestJS Applications

  • Organize Modules Logically: Group related functionality into modules to keep your codebase maintainable.
  • Use Global Modules Sparingly: You can make a module global with @Global(), but this can make dependency tracking harder. Prefer explicit imports.
  • Test Incrementally: After setting up cross-module injection, test with small endpoints to catch errors early.
  • Document Dependencies: Comment your module files to clarify which services are exported and why.

Conclusion

Injecting a service from another module in NestJS is straightforward once you understand the module system and dependency injection. By exporting the service, importing the module, and injecting the service, you can build modular, reusable applications with ease. If you hit errors, check your exports and imports arrays, and watch out for circular dependencies.

Have you faced this issue in your NestJS projects? Share your solutions or questions in the comments below—I’d love to hear from you!

Happy coding, and keep building modular NestJS apps!

About

Software Developer & Consultant specializing in JavaScript, TypeScript, and modern web technologies.

Share this article