Volt v0.1 · TypeScript APIs on Bun · Get started
Docs/Architecture & DI/Dependency Injection

Dependency Injection

Register explicit dependencies and resolve services at startup.

Complete service example

Use deps to declare constructor dependencies. The marker decorator alone does not wire constructor arguments in Container.resolve().

index.ts
import { Volt, Container } from 'voltts';

class ProductService {
  constructor(private label: string) {}
  list() { return [{ id: 1, title: this.label }]; }
}
const container = new Container();
container.registerValue('productLabel', 'Coffee');
container.register({
  provide: ProductService,
  useClass: ProductService,
  deps: ['productLabel'],
  lifetime: 'singleton',
});
container.init();
const service = container.resolve(ProductService);
const app = new Volt();
app.get('/products', () => ({ products: service.list() }));
if (globalThis._importMeta_.main) app.listen(3000);
export default app;

Verify the service

bash
bun run index.ts
curl http://localhost:3000/products

Expect {"products":[{"id":1,"title":"Coffee"}]}.

Providers and lifetimes

Container supports registerValue, class providers, and registerFactory. Explicit class providers accept deps and lifetime ('singleton', 'transient', or 'request'). init() resolves singleton providers and detects circular dependencies. Resolve services before starting the server when possible.

Scope boundaries

createScope() creates a child container, but parent registrations resolve in the parent. Request lifetimes are cached within the container that owns their registration; they are not automatically per HTTP request. Register request-specific providers in an explicit child container. Keep asynchronous factory initialization outside synchronous resolve().