NestJS Modules & Dependency Injection
Best-practices reference for organizing NestJS applications into encapsulated feature modules and wiring providers through the IoC container correctly. Covers module boundaries, provider visibility, dynamic modules, injection scopes, custom provider tokens, and circular dependencies.
When to Apply
- Designing or reviewing
@Modulestructure and feature boundaries - Registering providers and deciding what to
export - Building configurable libraries with
forRoot/forRootAsync - Choosing an injection scope (singleton vs REQUEST vs TRANSIENT)
- Wiring custom providers (
useClass/useValue/useFactory) and injection tokens - Resolving or avoiding circular dependencies
- Deciding whether a module should be
@Global()
Rules
feature-module-boundaries- one module per feature/domain; keep providers encapsulatedexport-shared-providers- only providers listed inexportsare visible to importing modulesdynamic-modules-forroot- configure reusable modules viaforRoot/forRootAsyncreturningDynamicModuleinjection-scopes-default-singleton- prefer default singleton scope; REQUEST scope bubbles up and hurts performancecustom-provider-tokens- useuseClass/useValue/useFactorywith injection tokens and interfacesconstructor-injection- prefer constructor injection over property injectionavoid-circular-dependencies- restructure first; useforwardRefonly as a last resortglobal-module-sparingly- reserve@Global()for truly cross-cutting modules (config, logger)
How to Use
Read individual rule files in rules/ for explanation + incorrect/correct examples.