Skip to main content

What is a provider?

A Provider in NestJS is any class that can be injected into other classes via the Dependency Injection (DI) system. Put simply, a provider is something that supplies functionality or data, usable by other components (controllers, services, guards, pipes, etc.).

The core idea

A provider is an object that NestJS creates and manages. Nest itself decides:

  • when to create the provider's instance;
  • how to inject it into the classes that need it;
  • how many copies should exist (a singleton, one shared instance, by default).

A simple provider example

javascript
import { Injectable } from '@nestjs/common'; @Injectable() export class UsersService { private users = [{ id: 1, name: 'John' }]; findAll() { return this.users; } }

This UsersService is a provider, because it's marked with the @Injectable() decorator. It can be injected into a controller or another service:

javascript
import { Controller, Get } from '@nestjs/common'; import { UsersService } from './users.service'; @Controller('users') export class UsersController { constructor(private readonly usersService: UsersService) {} @Get() getUsers() { return this.usersService.findAll(); } }

How NestJS creates and injects providers

  1. Every provider is registered in @Module() (under providers).
  2. NestJS puts all providers into the DI container (IoC container).
  3. When another class declares a dependency in its constructor, NestJS automatically finds and injects the right instance.

Types of providers

Provider typeExampleDescription
Class provider@Injectable() class UsersService {}The most common type
Value provider{ provide: 'CONFIG', useValue: { port: 3000 } }Returns a plain value or object
Factory provider{ provide: 'TOKEN', useFactory: () => new Date() }Creates a value dynamically via a function
Alias provider{ provide: 'Alias', useExisting: UsersService }Points to an already-existing provider
Custom-class provider{ provide: 'Logger', useClass: CustomLogger }Lets you swap a class's implementation

Examples of different providers

useValue

javascript
@Module({ providers: [ { provide: 'API_KEY', useValue: '12345' }, ], }) export class AppModule {}

Injection:

javascript
@Injectable() export class SomeService { constructor(@Inject('API_KEY') private apiKey: string) {} }

useFactory

javascript
@Module({ providers: [ { provide: 'RANDOM_NUMBER', useFactory: () => Math.random(), }, ], }) export class AppModule {}

useClass

javascript
@Injectable() class DefaultLogger { log(msg: string) { console.log('[Default]', msg); } } @Injectable() class CustomLogger { log(msg: string) { console.log('[Custom]', msg); } } @Module({ providers: [ { provide: DefaultLogger, useClass: CustomLogger }, ], }) export class AppModule {}

Now anywhere DefaultLogger is requested, CustomLogger is used instead.

Providers and Scope

By default a provider is a singleton, but its scope can be changed:

javascript
@Injectable({ scope: Scope.REQUEST }) export class RequestScopedService { // created fresh for every HTTP request }
ScopeDescription
Default (Singleton)One instance for the whole application
RequestA new instance for every request
TransientA new instance for every use

Where providers get registered

Usually inside a module:

javascript
@Module({ providers: [UsersService], exports: [UsersService], }) export class UsersModule {}

To use UsersService in another module:

javascript
@Module({ imports: [UsersModule], }) export class AuthModule {}

Summary

ConceptDescription
ProviderA class or value managed by NestJS's DI container
PurposeSupplying functionality, logic, or data to other parts of the app
Main tool@Injectable() and the Dependency Injection system
RegisteredUnder a module's providers
TypesuseClass, useValue, useFactory, useExisting

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.