Context
Apps, services and plain packages all need one way to declare modules, providers and dependencies. Two facts decide the mechanism. A single bundler (esbuild, as used by Encore) never emitsdesign:paramtypes, so type-based auto-wiring works
in some hosts and silently fails in others. And a Nest.js layer was rejected as a server framework (0011), while its vocabulary is
what people already know.
Decision
- One container package (
@stackra/container) with Nest-shaped names and signatures and zero@nestjs/*dependency. - Legacy (experimental) decorators are the declaration standard for modules, providers, scopes and metadata. The one
define*factory isdefineToken<T>(name), because a token has nothing to decorate. - Every constructor parameter names its token:
@Inject(token)or@Dependencies([...]). A class is its own token.design:paramtypesis never read andreflect-metadatais never a dependency; the container keeps its own metadata store. - Small pure helpers live in a support package, one subpath per concern, no root entry, no globals (
process,window), no decorators, no base classes, zero runtime dependencies. The container core never imports it. A helper is added only when a second package needs it. - Packages that use decorators extend the decorators presets:
@stackra/typescript-config/decorators, the oxlintdecoratorspreset, and the vitest decorators preset. Nothing else relaxesconsistent-type-importsorno-extraneous-class.
Consequences
- Wiring is explicit and identical in every host.
- Decorator metadata is not portable to a toolchain that drops legacy decorators; the presets are the single place to change that.
- Reflection helpers are not available. This is intended.
Enforcement
- The presets exist:
packages/tooling/typescript/src/decorators.json,packages/tooling/oxlint/src/decorators.jsonc,packages/tooling/vitest/src/preset-decorators.ts. FORBIDDEN_DEPENDENCIESintools/scripts/validate-repository.mjsrejects@nestjs/core,@nestjs/commonandreflect-metadata.- Planned: a check that no package other than the container imports the support package into a core entry.
Supersedes and sources
Supersedes: none. Sources: figentradocs/adr/0007-dependency-injection-container, 0009-support-package.