Skip to content

API reference ​

Introduction · Complete tutorial · Server recipes

Use this page to find an API and understand its role. The complete tutorial teaches the concepts with examples; the generated reference provides exact signatures, generic constraints, overloads, parameters, return types, and links to source declarations.

Generated reference ​

Entry pointWhat it exposes
di-bagPortable facade, public types, and structured library errors.

Start with the DiBagApi, Builder, and Container. The same builder seals a reusable Module. The reference represents these type-only exports as interfaces; construct values through DiBag.

The generated Markdown is committed alongside the source. CI compares it with fresh output and verifies public export and callable-overload coverage against the TypeScript compiler. See documentation maintenance for how to regenerate it.

API at a glance ​

Import DiBag and the error classes from di-bag. On Node, Bun, and Deno it detects native Promises itself; elsewhere see portable mode. The root import works on every supported runtime. Each table links to explanations and examples in the tutorial; the server guide puts them into an application.

Configure and describe services ​

These methods are available on DiBag and every derived facade. A provider is a reusable declaration; creating one does not acquire a service.

MethodResult and purpose
createProvider(factory, options?)Describe a named-dependency factory; specify a factory return kind outside Node, Bun, and Deno.
createProviderFromFunction({ dependencies, factoryFunction, ... })Inject positional token dependencies into a function.
createProviderFromClass({ dependencies, serviceClass, ... })Adapt a constructor to positional dependencies.
createProviderFromPlugin({ dependencies, pluginDescriptor, ... })Validate a selected plugin and its output.
createToken(symbol).forService<Service>() / .forCollectionOf<Service>()Create a single-service or collection token.
withConfiguration(options)Return a facade with inherited runtime settings and appended lifecycle observers.
optional(token)Supply undefined when a positional token dependency is unregistered.
lazy(token)Supply a function that resolves a positional token dependency when called.
createBuilder()Create an immutable builder for a container or module.
providerWithDisposal({ provider, disposeService })Give the container ownership of this provider's acquired value.
providerWithLifetime({ provider, lifetime })Choose singleton, scoped, or transient caching; scoped is the default.
providerWithRegistrationMetadata({ provider, registrationMetadata })Attach metadata available without acquiring the service.
providerWithAcquisitionMetadata({ provider, callbackReceives, describeAcquisition })Append one synchronous acquisition-metadata frame.
providerWithTransformedService({ provider, callbackReceives, transformService })Project an exposed service while retaining its ownership and graph contracts.

Build and reuse a graph ​

Builder operations return a new builder. Keep the returned value or chain the next call; they do not mutate the original.

MethodAvailable onPurpose
withServices(providersByName)BuilderAdd new string-named providers.
withTokenService(token, provider)BuilderBind a single-service token.
withServiceAlias({ aliasKey, targetServiceKey })BuilderAdd another lookup name for a service.
withCollectionContribution({ collectionToken, provider })BuilderAppend an ordered collection contribution.
withReplacedService(serviceKey, provider)BuilderReplace an existing binding with a compatible provider.
withInstalledModules(modules)BuilderInstall sealed modules in list order.
verifyGraphAtCompileTime()BuilderReport an incomplete graph through its TypeScript return type.
buildModule({ exportedServiceKeys, moduleLabel? })BuilderSeal public exports; unmet dependencies become module requirements.
buildContainer()BuilderCheck graph completeness and create a lazy owning container.
moduleLabelSealed ModuleRead the exact optional label supplied at sealing without acquiring a service; rename views preserve it.
withRenamedExport({ currentExportKey, newExportKey })Sealed ModuleReturn a module view with a renamed string export.
withRenamedRequirement({ currentRequirementKey, newRequirementKey })Sealed ModuleReturn a module view that asks its host for a renamed string requirement.

There is one builder. buildContainer() requires a complete graph; buildModule() records unmet dependencies as requirements. Modules do not resolve services or have a close method. Each installation allocates fresh private bindings.

Use and close a container ​

For each server request, create a child container, resolve its services, then close it after the response. Unmarked providers are scoped to each container.

MethodPurpose
resolve(serviceKey)Lazily acquire a single service with its inferred return type.
resolveCollection(token)Resolve ordered contributions as a frozen readonly list.
serviceSnapshot(serviceKey)Inspect service or collection metadata and acquisition state without acquiring anything.
graphSnapshot()Describe every binding, module installation, and dependency edge observed so far.
createChildContainer(options?) / createChildContainer(keys, providers, options?)Create a tracked child container with optional sharing and checked scoped or transient replacements.
createIndependentContainer() / createIndependentContainer(keys, providers)Create an independent container with fresh instances and optional checked replacements.
ensureServicesReady(serviceKeys, options?)Wait for selected services to become ready.
close(options?)Stop resolutions, drain work, and dispose owned resources; a timed or aborted wait can be cancelled.

Errors and recovery ​

Each library error code names a kind of failure, while details.operation names the method where it occurred. The errors page lists all codes and compile-time messages. Catch specialized error classes with instanceof when choosing a recovery path.

ErrorWhen it appearsPublic information
DiBagDisposalErrorclose() attempted every disposer and one or more failed.failures records each binding label and original error.
DiBagServiceReadinessErrorensureServicesReady() could not make a selected service ready.cause, disposalFailures, and disposalError retain the failure and disposal outcome.
DiBagServiceReadinessCancelledErrorAn abort signal or timeout stopped a readiness wait.reason, details.acquisitionsStillPending, and disposalPromise describe the cancellation and eventual disposal.
DiBagCloseCancelledErrorAn abort signal or timeout stopped a close() wait.details lists pending work; disposalPromise settles when disposal finishes.
DiBagPluginValidationErrorA plugin descriptor or acquired output failed validation.phase identifies the boundary and reason describes the rejection.

For a container whose disposer fails:

ts
import { DiBag, DiBagDisposalError } from 'di-bag';

const app = DiBag.createBuilder().withServices({
  resource: DiBag.providerWithDisposal({
    provider: () => ({ name: 'example' }),
    disposeService: () => { throw new Error('disposal failed'); },
  }),
}).buildContainer();
app.resolve('resource');

try {
  await app.close();
} catch (error) {
  if (error instanceof DiBagDisposalError) {
    for (const failure of error.failures) {
      console.error(failure.bindingLabel, failure.error);
    }
  }
  throw error;
}

Factory errors and transformation errors retain their original identity on resolution. Library-created failures expose stable DI_BAG_* codes and frozen structured details; inspect those fields instead of parsing message text. Observer callback failures are delivered to the observer's onObserverFailure callback and do not become service or shutdown failures. DI_BAG_INVALID_DEPENDENCY_ACCESS reports enumeration or in checks on a factory's dependency object; its details.consumer names the factory.

Exported TypeScript types ​

All names in this section are type-only exports from di-bag. Use import type for them. They provide annotations and preserve contracts in generated declarations; they do not provide unchecked runtime constructors.

For application code, prefer inferred values and typeof or ReturnType when passing a graph across a module boundary:

ts
import { DiBag, type ProviderOutput, type TokenService } from 'di-bag';

const clockSymbol = Symbol('clock');
const clock = DiBag.createToken(clockSymbol).forService<{ now(): number }>();
const stamp = DiBag.createProviderFromFunction({
  dependencies: [clock],
  factoryFunction: source => source.now(),
});
const app = DiBag.createBuilder()
  .withTokenService(clock, () => ({ now: () => 42 }))
  .withServices({ stamp })
  .buildContainer();

type Clock = TokenService<typeof clock>;
type Stamp = ProviderOutput<typeof stamp>;
type Application = typeof app;
await app.close();

These names refer to the clock, stamp provider, and app in the tutorial's typed-token example. Inferred types retain private-consumer, token, lifetime, and ownership contracts.

Application-facing types ​

ExportsPurpose
DiBagApiThe complete DiBag method surface, including configured and observed facades.
ConfigurationOptionsRuntime classification and observer options for withConfiguration.
Builder, ContainerA checked immutable builder and a resolving, owning container.
ModuleA sealed export view of a builder graph, installable in other builders.
ModuleOptionsOptional non-empty moduleLabel for naming private bindings; labels are descriptive and may repeat or contain /.
ProviderOrFactoryAccepted provider or factory shapes.
ProviderA provider description retaining its factory, metadata, frames, graph contracts, and acquired-value type.
FactoryReturnKind, RuntimeOptionsFactory return-kind literals and the isNativePromise configuration callback.
LifetimeSingleton, scoped, and transient caching choices; scoped is the default.
FactoryContext, ContextualFactory, DisposerContextFactory cancellation, contextual factory, and disposal callback contracts.
EnsureServicesReadyOptionsOptional abortSignal, totalTimeoutMs, and maxConcurrentServiceKeys fields for ensureServicesReady.
CloseOptions, CloseProgressClose wait controls and pending work reported after cancellation.
CreateChildContainerOptions, CreateIndependentContainerOptionsChecked selections accepted when deriving child and independent containers.
Token, TokenBase, TokenKey, TokenKind, TokenServiceSingle-service token identity, common handle, kind, and key/service projections.
CollectionToken, CollectionTokenBase, CollectionItemCollection token identity and the type of one contribution.
OptionalDependency, LazyDependency, DependencyReferenceThe token reference forms accepted in positional dependency tuples.
PositionalFactoryArguments, PositionalFactoryFunctionPositional argument compatibility and callback signatures for function/constructor adaptation.
Presence{ isPresent: false } or { isPresent: true, value }, including a present undefined value.
AcquisitionMetadataPresence, AcquisitionSnapshot, RegistrationSnapshotInspection frames, acquisition state, and registration metadata snapshots.
GraphSnapshot, BindingSnapshot, ModuleInstallationSnapshotThe frozen graph description, per-binding origin, and installation records with parent IDs.
DisposalFailureThe detached acquisition identity, label, and original disposal error.
DiBagErrorCode, DiBagDiagnosticStable library error codes and their structured diagnostic fields.
LifecycleObserver, ObserverCallback, ObserverErrorCallbackObserver configuration and its event/failure callbacks.
LifecycleEvent, ObserverFailure, ContainerEventFields, AcquisitionEventFieldsDiscriminated lifecycle events and observer failure context.
PluginReturnKind, CreateProviderFromPluginOptions, PluginOutputValidator, PluginProviderPlugin return policy, validation options, output predicate, and resulting provider.
CreateProviderFromPluginThe callable type of DiBag.createProviderFromPlugin; use it directly as a type.
CompositionReportThe compile-time verdict for a builder: void when buildable, otherwise the buildContainer() failure with details.
DiBagPolicyEmpty interface for project-wide compile-time switches; augment with structuralThenables: 'allow' to relax the thenable check.

Provider and module projections ​

ExportsPurpose
ProviderFactory, ProviderOutput, ProviderAcquiredValue, ProviderNamedDependenciesExtract the factory, exposed result, acquired value, and named requirements from a registration. Output and acquired value can differ across async boundaries.
ProviderRegistrationMetadata, ProviderAcquisitionMetadataExtract static metadata and the tuple of acquisition metadata frames.
ProviderGraphContractRetain a provider's token and other graph obligations.
ProviderRequiredTokens, ProviderOptionalTokens, ProviderCollectionTokensExtract required/lazy, optional, and collection token requirements.
ModuleExportedServices, ModuleRequiredServicesExtract the readonly service exports and external requirements of a sealed module.
ModuleConstraintsCompute retained private-consumer and lifetime constraints for a registration map and public selection.
SealedConstraints, ModuleSealedConstraintsRebase constraints retained from installed modules when a builder seals; the complete constraint set of a sealed module.
PublicProviders, ModulePublicProvidersPreserve provider contracts when projecting public module registrations.
RenamedRepresent the checked renaming of a module's public view.

Graph composition support types ​

These exports support reusable generic helpers and portable declaration output. Most applications can let the builder infer them. They express compile-time contracts; they do not perform runtime validation.

ExportsPurpose
ServicesOfMap providers to their exposed service types.
RegistrationEntries, RegistrationsFromEntriesConvert between a registration map and its entry representation.
OverrideRegistrations, SelectedRegistrationsModel merged registration maps and selected override registrations.
CheckDependencyCompatibility, CheckDependencyCompletenessCheck dependency shape compatibility and graph completeness.
Selection, Overrides, OverrideFactoryContextValidate selections and replacement compatibility while preserving contextual inference.
TokenBinding, TokenMember, TokenDependencyContractRetain typed bindings, validate token membership, and represent token obligations.
CollectionTokenMember, SingleServiceTokenMemberCheck collection and single-service token membership.
ReboundProviders, ReboundSelection, SelectionKeyPreserve token bindings across replacement and map selections to their string/symbol keys.
AliasRegistration, AliasEntries, AliasOutputModel an alias registration, its graph entries, and its exposed result.
Contribution, ContributionConstraintDescribe an ordered contribution and its retained requirements.
ModuleContributions, ModuleContributionConstraintsPreserve contributions and their requirements in modules.
BuilderWithCollectionContributionThe checked collection-contribution callable on the builder.
BuilderBuildModule, BuilderWithInstalledModules, BuilderWithReplacedServiceChecked module sealing, installation, and replacement call signatures.
BuilderWithServiceAlias, BuilderWithServices, BuilderWithTokenServiceChecked alias and service registration call signatures.
DisjointChildContainerSelectionEnforce separate override and sharing selections.
UnsharedAliases, ScopedAliases, SharedAliasProvidersPreserve alias contracts as child containers inherit or explicitly share services.
CanonicalLifetime, LifetimeObligation, ReachNormalize lifetimes and retain compact module lifetime obligations.
CheckedLifetimes, CheckedChildContainerLifetimes, ChildReplacementAdmissionCheck singleton capture and child replacement compatibility.

The authoritative export list is src/index.ts. Internal helpers in other source files are not package exports.

Boundaries ​

  • Token maps and dependency parameters must have finite string keys. Index signatures, including open template keys, cannot prove that tokens exist.
  • Containers are created through checked builders and independent containers. Container is exported as a type only; there is no public unchecked constructor.
  • Parameters may be omitted or be a single object type. Optional dependency properties still require providers. Union, callable, and symbol-keyed dependency parameter types are rejected.
  • Dependency proxies support named property reads. Do not enumerate, spread, or use rest destructuring on them: parameter types are erased at runtime, so the container cannot enumerate a particular factory's declared requirements.
  • Use a single, explicit factory signature. TypeScript utility types see the last signature of overloaded functions; arbitrary overload behavior cannot be inferred. As with other TypeScript APIs, casts and unchecked JavaScript can bypass compile-time checks; runtime resolution still checks missing tokens.
  • JavaScript output targets ES2022. The CommonJS package supports Node require and ESM named imports, and browsers through a bundler. Bun is only needed to run the development tests. The supported compiler floor and development type checks use TypeScript 6.0.3.

Usage topics ​

The detailed examples live in the complete tutorial. These links also preserve existing bookmarks into the earlier combined guide.

Compose services ​

Read the tutorial section.

Reuse named modules ​

Read the tutorial section.

Use typed tokens for explicit positional injection ​

Read the tutorial section.

Adapt classes and positional functions ​

Read the tutorial section.

Declare optional and lazy dependencies ​

Read the tutorial section.

Give a dependency another lookup name ​

Read the tutorial section.

Compose an ordered collection ​

Read the tutorial section.

Attach metadata and inspect without resolving ​

Read the tutorial section.

Observe lifecycle transitions ​

Read the tutorial section.

Admit an application-selected plugin ​

Read the tutorial section.

Async edges are explicit ​

Read the tutorial section.

Project services explicitly ​

Read the tutorial section.

Attach disposal with providerWithDisposal ​

Read the tutorial section.

Make selected services ready, and cancel cooperatively ​

Read the tutorial section.

Choose a lifetime: singleton, scoped or transient ​

Read the tutorial section.

Create child containers ​

Read the tutorial section.

Create an independent container for tests ​

Read the tutorial section.

WBS-shaped ownership example ​

Read the tutorial section.

Represent acquisition values and metadata natively ​

Read the tutorial section.

Ordinary services. Checked composition. Explicit ownership.