Custom Providers

Provide a Class, Value, Factory, or Existing Token

Custom Providers

The shorthand `providers: [UsersService]` is just one option — Nest also supports useClass, useValue, useFactory, and useExisting.

4 min read Level 3/5 #nestjs#di#providers
What you'll learn
  • Swap implementations with useClass
  • Inject constants with useValue
  • Alias one token to another with useExisting

providers: [UsersService] is shorthand for the long form. Behind the scenes it expands to { provide: UsersService, useClass: UsersService }. Knowing the long form unlocks testing, configuration, and aliasing.

useClass — Swap an Implementation

The token (provide) stays the same, but the class behind it changes. Perfect for swapping in a mock during testing.

@Module({
  providers: [
    {
      provide: UsersService,
      useClass: process.env.NODE_ENV === 'test'
        ? MockUsersService
        : UsersService,
    },
  ],
})
export class UsersModule {}

Anywhere UsersService is injected, the chosen class is built. Consumers don’t change a line.

useValue — Inject a Literal

When the “dependency” is just data — config, a constant, a stub object — use useValue. The provided value is returned as-is; nothing is constructed.

@Module({
  providers: [
    { provide: 'CONFIG', useValue: { port: 3000, env: 'production' } },
    { provide: 'FEATURE_FLAGS', useValue: new Set(['beta-ui', 'fast-cache']) },
  ],
})
export class AppModule {}

// Consumer
@Injectable()
export class HttpServer {
  constructor(@Inject('CONFIG') private readonly cfg: { port: number }) {}
}

For tests, useValue is the easiest way to drop in a hand-rolled stub:

const moduleRef = await Test.createTestingModule({
  providers: [
    OrdersService,
    { provide: PaymentsService, useValue: { charge: jest.fn() } },
  ],
}).compile();

useExisting — Alias a Token

useExisting makes one token point to another already-registered provider. The container doesn’t build twice; both tokens resolve to the same instance.

@Module({
  providers: [
    LoggerService,
    { provide: 'APP_LOGGER', useExisting: LoggerService },
  ],
  exports: ['APP_LOGGER', LoggerService],
})
export class LoggerModule {}

Use it to keep a legacy string token alive while migrating consumers to the class reference, or to expose a single instance under multiple names.

Picking the Right Form

You wantUse
The default behaviorshorthand
A different class for the tokenuseClass
A constant, plain object, or stubuseValue
Two tokens for one instanceuseExisting
A computed/async dependencyuseFactory

That last one — useFactory — is powerful enough to deserve its own lesson.

Factory Providers →