Under The Hood
backend nestjs NestJS 10+ (on top of TypeScript/Express)

NestJS dependency injection container

Last updated
Prerequisites:
TypeScript decorators basics
NestJS modules and providers
  • nestjs
  • dependency-injection
  • container
  • typescript
  • reflect-metadata
  • decorators

Read at your depth

The practical view

In NestJS you mark a service with @Injectable(), list it in a module's providers, and inject it via a constructor parameter: constructor(private readonly usersService: UsersService) {}. Nest resolves the graph at bootstrap: it instantiates the provider (and all its transitive dependencies), caches it per the provider scope (DEFAULT = singleton per application, REQUEST = per request, TRANSIENT = per injection), and injects it where requested. Injection happens via the TypeScript design:paramtypes metadata that the compiler emits when decorators are present (reflect-metadata + emitDecoratorMetadata).

Legacy vs modern

Manual service wiring vs Nest DI container

Hand-constructed services tangle creation order and make swaps invasive; the container resolves the graph, applies scope, and enables clean test substitution.

before → after
Manual wiring
const repo = new UserRepository(db);
const svc = new UserService(repo);
const ctrl = new UserController(svc);
Nest DI
@Injectable()
export class UserService {
  constructor(private readonly repo: UserRepository) {}
}

Interview gotchas

Under The Hood — a multi-depth technical interview hub.

Press ⌘ K to search.