DI
Angular's dependency injection with the sharp edges filed off. Typed token-and-provider pairs instead of InjectionToken boilerplate, services that lazy-load their own code chunk, and factory-built singletons. Each is a thin named helper over the DI you already use.
@mmstack/dinpm
npm install @mmstack/di These sit on top of Angular's own DI rather than replacing it. If inject() or providedIn: 'root' already fits, use those. Reach for these when the boilerplate or the timing gets in the way.
#Picking one
| You want to | Reach for |
|---|---|
| A typed token with a provide/inject pair, no boilerplate | injectable |
| Defer constructing an already-bundled service until first use | injectLazy |
| Lazy-load the code for a non-root service, or support v19 to v21 | injectAsync |
| Declare a lazy dependency in providers, inject it deep below | provideLazy |
| A factory-built app-wide singleton | rootInjectable |
| Factory-built singletons scoped to a component subtree | createScope |
Run inject() later, in a callback that lost context | createRunInInjectionContext |
On Angular v22 and up, if the service you want to lazy-load is auto-provided (providedIn: 'root' or @Service()), Angular's own injectAsync is all you need. This library's version is for the cases the built-in cannot cover.
#A note on SSR
The fallbacks on injectable and rootInjectable singletons are token factories, which Angular caches per root injector. Every server request gets its own root injector, so each request builds its own instance. You can define these at module scope without state leaking between requests, tests, or multiple apps on a page.