23:18 6/7/25 Providers | NestJS - A progressive Node.
js framework
dark_mode
https://docs.nestjs.com/providers 1/9
23:18 6/7/25 Providers | NestJS - A progressive Node.js framework
Providers
Providers are a core concept in Nest. Many of the basic Nest classes, such as services, repositories, factories, and
helpers, can be treated as providers. The key idea behind a provider is that it can be injected as a dependency,
allowing objects to form various relationships with each other. The responsibility of "wiring up" these objects is
largely handled by the Nest runtime system.
In the previous chapter, we created a simple CatsController . Controllers should handle HTTP requests and
delegate more complex tasks to providers. Providers are plain JavaScript classes declared as providers in a
NestJS module. For more details, refer to the "Modules" chapter.
HINT
Since Nest enables you to design and organize dependencies in an object-oriented manner, we strongly
recommend following the SOLID principles.
Services
Let's begin by creating a simple CatsService . This service will handle data storage and retrieval, and it will be
used by the CatsController . Because of its role in managing the application's logic, it’s an ideal candidate to be
defined as a provider.
https://docs.nestjs.com/providers 2/9
23:18 6/7/25 Providers | NestJS - A progressive Node.js framework
cats.service.ts JS
import { Injectable } from '@nestjs/common'; content_copy
import { Cat } from './interfaces/cat.interface';
@Injectable()
export class CatsService {
private readonly cats: Cat[] = [];
create(cat: Cat) {
this.cats.push(cat);
}
findAll(): Cat[] {
return this.cats;
}
}
HINT
To create a service using the CLI, simply execute the $ nest g service cats command.
Our CatsService is a basic class with one property and two methods. The key addition here is the
@Injectable() decorator. This decorator attaches metadata to the class, signaling that CatsService is a class
that can be managed by the Nest IoC container.
Additionally, this example makes use of a Cat interface, which likely looks something like this:
interfaces/cat.interface.ts JS
export interface Cat { content_copy
name: string;
age: number;
breed: string;
}
https://docs.nestjs.com/providers 3/9
23:18 6/7/25 Providers | NestJS - A progressive Node.js framework
Now that we have a service class to retrieve cats, let's use it inside the CatsController :
cats.controller.ts JS
import { Controller, Get, Post, Body } from '@nestjs/common'; content_copy
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';
@Controller('cats')
export class CatsController {
constructor(private catsService: CatsService) {}
@Post()
async create(@Body() createCatDto: CreateCatDto) {
this.catsService.create(createCatDto);
}
@Get()
async findAll(): Promise<Cat[]> {
return this.catsService.findAll();
}
}
The CatsService is injected through the class constructor. Notice the use of the private keyword. This
shorthand allows us to both declare and initialize the catsService member in the same line, streamlining the
process.
Dependency injection
Nest is built around the powerful design pattern known as Dependency Injection. We highly recommend reading a
great article about this concept in the official Angular documentation.
In Nest, thanks to TypeScript's capabilities, managing dependencies is straightforward because they are resolved
based on their type. In the example below, Nest will resolve the catsService by creating and returning an
instance of CatsService (or, in the case of a singleton, returning the existing instance if it has already been
requested elsewhere). This dependency is then injected into your controller's constructor (or assigned to the
specified property):
https://docs.nestjs.com/providers 4/9
23:18 6/7/25 Providers | NestJS - A progressive Node.js framework
constructor(private catsService: CatsService) {} content_copy
Scopes
Providers typically have a lifetime ("scope") that aligns with the application lifecycle. When the application is
bootstrapped, each dependency must be resolved, meaning every provider gets instantiated. Similarly, when the
application shuts down, all providers are destroyed. However, it’s also possible to make a provider request-scoped,
meaning its lifetime is tied to a specific request rather than the application's lifecycle. You can learn more about
these techniques in the Injection Scopes chapter.
Learn the right way!
80+ chapters Official certificate
5+ hours of videos Deep-dive sessions
EXPLORE OFFICIAL COURSES
Custom providers
Nest comes with a built-in inversion of control ("IoC") container that manages the relationships between providers.
This feature is the foundation of dependency injection, but it’s actually much more powerful than we've covered so
far. There are several ways to define a provider: you can use plain values, classes, and both asynchronous or
synchronous factories. For more examples of defining providers, check out the Dependency Injection chapter.
Optional providers
Occasionally, you may have dependencies that don't always need to be resolved. For example, your class might
depend on a configuration object, but if none is provided, default values should be used. In such cases, the
dependency is considered optional, and the absence of the configuration provider should not result in an error.
To mark a provider as optional, use the @Optional() decorator in the constructor's signature.
import { Injectable, Optional, Inject } from '@nestjs/common'; content_copy
https://docs.nestjs.com/providers 5/9
23:18 6/7/25 Providers | NestJS - A progressive Node.js framework
po t { jectab e, Opt o a , ject } o @ estjs/co o ; content_copy
@Injectable()
export class HttpService<T> {
constructor(@Optional() @Inject('HTTP_OPTIONS') private httpClient: T) {}
}
In the example above, we're using a custom provider, which is why we include the HTTP_OPTIONS custom token.
Previous examples demonstrated constructor-based injection, where a dependency is indicated through a class in
the constructor. For more details on custom providers and how their associated tokens work, check out the Custom
Providers chapter.
Property-based injection
The technique we've used so far is called constructor-based injection, where providers are injected through the
constructor method. In certain specific cases, property-based injection can be useful. For example, if your top-level
class depends on one or more providers, passing them all the way up through super() in sub-classes can become
cumbersome. To avoid this, you can use the @Inject() decorator directly at the property level.
import { Injectable, Inject } from '@nestjs/common'; content_copy
@Injectable()
export class HttpService<T> {
@Inject('HTTP_OPTIONS')
private readonly httpClient: T;
}
WARNING
If your class doesn't extend another class, it's generally better to use constructor-based injection. The
constructor clearly specifies which dependencies are required, offering better visibility and making the code
easier to understand compared to class properties annotated with @Inject .
Provider registration
Now that we've defined a provider ( CatsService ) and a consumer ( CatsController ), we need to register the
service with Nest so that it can handle the injection. This is done by editing the module file ( app.module.ts ) and
adding the service to the providers array in the @Module() decorator.
https://docs.nestjs.com/providers 6/9
23:18 6/7/25 Providers | NestJS - A progressive Node.js framework
adding the service to the providers array in the @Module() decorator.
app.module.ts JS
import { Module } from '@nestjs/common'; content_copy
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';
@Module({
controllers: [CatsController],
providers: [CatsService],
})
export class AppModule {}
Nest will now be able to resolve the dependencies of the CatsController class.
At this point, our directory structure should look like this:
src
cats
dto
create-cat.dto.ts
interfaces
cat.interface.ts
cats.controller.ts
cats.service.ts
app.module.ts
main.ts
Manual instantiation
So far, we've covered how Nest automatically handles most of the details of resolving dependencies. However, in
some cases, you might need to step outside of the built-in Dependency Injection system and manually retrieve or
instantiate providers. Two such techniques are briefly discussed below.
To retrieve existing instances or instantiate providers dynamically, you can use the Module reference.
https://docs.nestjs.com/providers 7/9
23:18 6/7/25 g Providers
p | NestJS -yA progressivey Node.js
y framework
To get providers within the bootstrap() function (e.g., for standalone applications or to use a configuration
service during bootstrapping), check out Standalone applications.
Support us
Nest is an MIT-licensed open source project. It can grow thanks to the support of these awesome people. If you'd
like to join them, please read more here.
Principal Sponsors Sponsors / Partners
Become a sponsor
Join our Newsletter
Subscribe to stay up to date with the latest Nest updates, features, and videos!
Email address..
Copyright © 2017-2025 MIT by Kamil Mysliwiec design by Jakub Staron
Official NestJS Consulting Trilon.io hosted by Netlify
https://docs.nestjs.com/providers 8/9
23:18 6/7/25 Providers | NestJS - A progressive Node.js framework
https://docs.nestjs.com/providers 9/9