Show HN: Ampulla: Modern TypeScript DI with NestJS Ergonomics

murmansk1 pts0 comments

Yes, yet another DI library for TypeScript.A few things kept bothering me about the existing ones, in order of how much they hurt.- *Type safety requires a special dance.* InversifyJS has ServiceIdentifier T , but it is really easy to break the typing. TypeDI tokens are untyped strings. NestJS suffers mostly same, unless you use full classes as dependency tokens. TSyringe infers from constructor metadata, but all of it relies on legacy reflect-metadata and decorators mechanism that (a) is soon to be gone, (b) requires additional wiring.- *Async leaks into callers.* InversifyJS has container.getAsync() for providers that might have been initialized asynchronously. That means every call site needs to know whether what it s asking for was async. The complexity never stays contained. NestJS again gets this right: await everything at bootstrap, then get() is always synchronous. Initialized means ready.- *Wiring is imperative.* InversifyJS has you call manually .bind(Token).to(Implementation) for every provider. It works, but it s ugly. NestJS figured out the right answer: declare what a module owns, what it needs, what it exposes, and let the container figure the rest out. That declarative model is the thing I wanted most, but it comes with an entire framework. NestJS gets hairy when your single app starts accepting just Nats JetStream in addition to HTTP.- *reflect-metadata.* Every major TS DI library runs on TS experimentalDecorators plus a global runtime polyfill for TypeScript metadata. TC39 Stage 3 decorators shipped in TypeScript 5.0, and are soon to be natively supported in JS engines. No flags, no polyfills.Ampulla is my attempt at fixing all four: injection T () tokens that carry their type intrinsically, a declarative @Module/@Injectable model lifted straight from NestJS, async-safe bootstrapping where container.get() is always synchronous, and TC39 decorators throughout.It s intentionally just a DI container, not a framework. There is no HTTP server, no router, no CLI included. Optional adapters for Hono and H3 are included but tree-shakeable. The whole npm package has zero runtime dependencies.Very early, 1.0.0 published just today. DI is not the most popular topic on HN, but existing DI in TypeScript is annoying enough that I had to publish something new.GitHub: https://github.com/ukstv/ampulla | npm: npm install ampulla

nestjs ampulla typescript metadata inversifyjs tokens

Related Articles