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 point | What it exposes |
|---|---|
di-bag | Portable facade, public types, and structured library errors. |
di-bag/node | The same API with Node/Bun native-Promise detection configured. |
Start with the DiBagApi, Builder, and Bag. 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. di-bag/node is the explicit Node/Bun form. Both entries expose the same methods and types. 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.
| Method | Result and purpose |
|---|---|
createBuilder() | Create an empty immutable builder that can build a bag or seal a module. |
withConfiguration({ runtime?, observers? }) | Return a new facade; inherit omitted runtime options and append the ordered observer array. |
fromFactory(create, options?) | Describe a named-dependency factory; acquisitionMode defaults to auto. Add context: 'acquisition' to supply the owner's cancellation context. |
fromSyncFactory(create, options?) | fromFactory with acquisitionMode: 'raw' fixed and a Promise or thenable output rejected at compile time: the portable synchronous form. |
fromAsyncFactory(create, options?) | fromFactory with acquisitionMode: 'nativePromise' fixed and a non-Promise output rejected: the portable asynchronous form; withDisposal receives the fulfilled value. |
token(key).of<Service>() | Create a typed token from a canonical unique symbol. |
fromFunction(dependencies, fn, options?) | Inject a tuple of tokens/references into a positional callback, checking its actual optional/rest parameter tuple. Write selected but unused parameters explicitly. |
fromClass(dependencies, Constructor, options?) | Adapt an existing constructor. |
optional(token) / lazy(token) / all(token) | Supply an optional value, lazy lookup, or ordered collection through a positional dependency tuple. |
fromPlugin(dependencies, descriptor, options) | Validate a selected plugin with explicit acquisitionMode: 'raw' or 'nativePromise' and a synchronous output validator. |
withDisposal(registration, dispose) | Accept cleanup ownership of that stage's acquired value. |
withLifetime(registration, lifetime, options?) | Select root, scoped, or transient; only root accepts allowScopedDependencies. |
withMetadata(registration, { static?, dynamic? }) | Attach registration metadata, acquisition metadata, or both. Dynamic options require mode and synchronous describe. |
transformService(registration, { mode, transform, acquisitionMode? }) | Expose a transformed service, retaining earlier ownership; output acquisition options apply only to direct mode. |
direct passes the exact source output and preserves the callback result. awaited waits for the source and exposes a native Promise. Transformation callbacks may return Promises. Metadata callbacks must synchronously return plain object records; direct metadata preserves its source acquisition policy. Static-only metadata preserves the source output. Each dynamic annotation appends one ordered metadata presence frame; no metadata or transformation adds ownership.
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.
| Method | Available on | Purpose |
|---|---|---|
register(registrations) | Builder | Add new named factories; duplicate keys reject. |
register(token, registration) | Builder | Bind a typed token. |
replace(nameOrToken, registration) | Builder | Replace one existing registration while checking its consumers and token contract. |
alias(destination, target) | Builder | Add another name or token lookup for an existing service. |
contribute(token, registration) | Builder | Append an ordered contribution. |
installModule(module) | Builder | Install a sealed module with private services and public exports; modules nest. |
build() | Builder | Check graph completeness and return a lazy bag. |
buildAndStart(keys, options?) | Builder | Return a promise for a fresh bag after selected services are ready. |
buildModule(keys, { label? }) | Builder | Seal the graph as a module and choose its public names and tokens; unmet dependencies become requirements. A label names private bindings <label>/<key> in diagnostics. |
verifyGraph() | Builder | Runtime no-op whose return type is void only when the graph would build. |
renameExport(oldName, newName) | Sealed Module | Return a module view with one string-named export renamed. |
There is one builder. build() requires a complete graph; buildModule(keys) accepts an incomplete one and records the gaps as requirements of the module. Modules do not resolve services or have a close method. Installing a module gives its acquisitions an owning bag and fresh private identities at every nesting depth.
Use and close a bag
| Method | Purpose |
|---|---|
resolve(nameOrToken) | Lazily acquire a service, preserving its inferred return type. |
resolveAll(token) | Resolve the ordered contributions as a readonly array. |
inspect(nameOrToken) | Copy metadata and acquisition state without resolving. |
inspectAll(token) | Inspect contribution descriptions and attempts without resolving. |
inspectGraph() | Describe every binding, contribution group, and observed edge without resolving. |
createScope() | Create a tracked child scope. |
createScope({ share: keys }) | Create a child that explicitly borrows selected parent acquisitions. |
createScope(keys, overrides, options?) | Create a child with checked replacements and optional disjoint share selection. |
fork() | Create an independent bag with fresh instances. |
fork(keys, overrides) | Create an independent bag with selected replacements. |
close() | Return the shutdown promise; stop new resolutions, drain work, and dispose owned resources. Repeated calls share the same promise. |
close({ timeoutMs?, signal? }) | Start the same cleanup but stop waiting at the deadline or on abort with DiBagCloseCancelledError. |
Errors and recovery
Every library-created message has the form <code>: <message>; see https://dany-fedorov.github.io/di-bag/agent/errors.html#<code-slug>, where the slug is the code lower-cased with _ replaced by -. For example: DI_BAG_CYCLE: cycle: a -> b -> a; see https://dany-fedorov.github.io/di-bag/agent/errors.html#di-bag-cycle. The errors page has one section per code and per compile-time message family.
The specialized error classes below are runtime exports from both di-bag and di-bag/node. Each extends the built-in Error family and has a corresponding name. Catch them with instanceof when choosing a recovery path.
| Error | When it appears | Public information |
|---|---|---|
DiBagCleanupError | close() finishes attempting cleanup and one or more disposers failed. | Extends AggregateError; errors contains the original errors, and readonly failures associates each with acquisitionId, bindingId, label, and error. |
DiBagPluginValidationError | A plugin descriptor or acquired output fails the plugin boundary checks. | phase is 'descriptor' or 'output'; reason describes the rejection. |
DiBagStartupError | Selected startup acquisition fails and rollback has completed. | cause is the acquisition error; cleanupFailures contains disposal failures; cleanupError retains the complete cleanup error when present. |
DiBagStartupCancelledError | An external signal or startup deadline interrupts startup. | reason is 'aborted' or 'timeout'; cause retains the cancellation reason; cleanupPromise is a Promise<void> for eventual shutdown. |
DiBagCloseCancelledError | close({ timeoutMs, signal }) stops waiting before cleanup finishes. | code is DI_BAG_CLOSE_TIMEOUT or DI_BAG_CLOSE_ABORTED; details.pending lists unfinished disposer labels and details.acquiring pending acquisitions; cleanupPromise settles when cleanup finishes. |
Given an existing application bag named app:
import { DiBagCleanupError } from 'di-bag';
try {
await app.close();
} catch (error) {
if (error instanceof DiBagCleanupError) {
for (const failure of error.failures) {
console.error(failure.label, failure.error);
}
}
throw error;
}Constructors are new DiBagCleanupError(failures), new DiBagPluginValidationError(phase, reason), new DiBagStartupError(cause, cleanupFailures, cleanupError?), new DiBagStartupCancelledError(reason, cause, cleanupPromise), and new DiBagCloseCancelledError(reason, cause, cleanupPromise, progress, timeoutMs?). Applications usually catch errors created by the library rather than constructing them.
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 onError 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 and di-bag/node. 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:
import type { ProviderOutput, TokenService } from 'di-bag';
type Clock = TokenService<typeof clock>;
type Stamp = ProviderOutput<typeof stamp>;
type Application = typeof app;These names refer to the clock, stamp registration, and app in the tutorial’s typed-token example. Shorter Bag, Module, or Provider annotations cannot erase retained private-consumer, token, lifetime, or ownership contracts.
Application-facing types
| Exports | Purpose |
|---|---|
DiBagApi | The complete DiBag method surface, including configured and observed facades. |
ConfigurationOptions | Runtime classification and observer options for withConfiguration. |
Builder, Bag | A checked immutable builder and a resolving/owning bag. |
Module | A sealed export view of a builder graph, installable in other builders. |
Registration, FactoryWithDisposal | Accepted registration shapes and an owned factory description. |
Provider | A provider description retaining its factory, metadata, frames, graph contracts, and acquired-value type. |
AcquisitionMode, RuntimeOptions | Acquisition mode literals and the isNativePromise configuration callback. |
Lifetime | The 'root', 'scoped', and 'transient' caching choices. |
AcquisitionContext, ContextualFactory | Factory cancellation context (signal) and the adapted contextual factory signature. |
StartupOptions | Optional signal, timeoutMs, and startupOrder fields for buildAndStart. |
ScopeOptions | The checked share selection accepted by createScope. |
Token, TokenBase, TokenKey, TokenService | Typed token identity, its common handle type, and key/service projections. |
OptionalDependency, LazyDependency, CollectionDependency, DependencyReference | The token reference forms accepted in positional dependency tuples. |
CompositionArguments, CompositionFunction | Positional argument compatibility and callback signatures for function/constructor adaptation. |
Presence | { present: false } or { present: true, value }, including present undefined. |
AcquisitionMetadataPresence, AcquisitionSnapshot, RegistrationSnapshot | Inspection frames, acquisition state, and registration metadata snapshots. |
GraphSnapshot, BindingSnapshot | The frozen result of inspectGraph() and its per-binding entries. |
CleanupFailure | The detached acquisition identity, label, and original cleanup error. |
DiBagErrorCode, DiBagDiagnostic | Stable library error codes and their structured diagnostic fields. |
ObserverOptions, ObserverCallback, ObserverErrorCallback | Observer configuration and its event/failure callbacks. |
LifecycleEvent, ObserverFailure, ScopeEventFields, AcquisitionEventFields | Discriminated lifecycle events and observer failure context. |
PluginAcquisitionMode, PluginOptions, PluginOutputValidator, PluginProvider | Plugin mode, validation options, output predicate, and resulting provider. |
PluginProviderFactory | The callable type of DiBag.fromPlugin; use it directly as a type. |
CompositionReport | The compile-time verdict for a builder: void when buildable, otherwise the build() failure with details. |
DiBagPolicy | Empty interface for project-wide compile-time switches; augment with structuralThenables: 'allow' to relax the thenable check. |
Provider and module projections
| Exports | Purpose |
|---|---|
ProviderFactory, ProviderOutput, ProviderAcquiredValue, ProviderNamedDependencies | Extract the factory, exposed result, acquired value, and named requirements from a registration. Output and acquired value can differ across async boundaries. |
ProviderRegistrationMetadata, ProviderAcquisitionMetadata | Extract static metadata and the tuple of acquisition metadata frames. |
ProviderGraphContract | Retain a provider's token and other graph obligations. |
ProviderRequiredTokens, ProviderOptionalTokens, ProviderCollectionTokens | Extract required/lazy, optional, and collection token requirements. |
ModuleExportedServices, ModuleRequiredServices | Extract the readonly service exports and external requirements of a sealed module. |
ModuleConstraints | Compute retained private-consumer and lifetime constraints for a registration map and public selection. |
SealedConstraints, ModuleSealedConstraints | Re-scope constraints retained from installed modules when a builder seals; the complete constraint set of a sealed module. |
PublicProviders, ModulePublicProviders | Preserve provider contracts when projecting public module registrations. |
Renamed | Represent 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.
| Exports | Purpose |
|---|---|
ServicesOf | Map registrations to their exposed service types. |
RegistrationEntries, RegistrationsFromEntries | Convert between a registration map and its entry representation. |
OverrideRegistrations, SelectedRegistrations | Model merged registration maps and selected override registrations. |
CheckDependencyCompatibility, CheckDependencyCompleteness | Check dependency shape compatibility and graph completeness. |
Selection, Overrides, OverrideFactoryContext | Validate selections and replacement compatibility while preserving contextual inference. |
TokenBinding, TokenMember, TokenDependencyContract | Retain typed bindings, validate token membership, and represent token obligations. |
ReboundProviders, ReboundSelection, SelectionKey | Preserve token bindings across replacement and map selections to their string/symbol keys. |
AliasRegistration, AliasEntries, AliasOutput | Model an alias registration, its graph entries, and its exposed result. |
Contribution, ContributionConstraint | Describe an ordered contribution and its retained requirements. |
ModuleContributions, ModuleContributionConstraints | Preserve contributions and their requirements in modules. |
BuilderContribute | The generic contribute signature on the builder. |
DisjointScopeSelection | Enforce separate override and sharing selections. |
UnsharedAliases, ScopedAliases, SharedAliasProviders | Preserve alias contracts as scopes inherit or explicitly share services. |
CheckedLifetimes, CheckedScopeLifetimes | Check root capture and lifetime compatibility in completed graphs and scope overrides. |
LifetimeObligation, Reach | Compact seal-time lifetime records a module retains instead of its private registrations. |
The authoritative export lists are src/index.ts and src/node.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.
- Bags are created through checked builders and forks.
Bagis 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 bag 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
requireand 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.