Modern Type-Safe Dependency Injection Without Reflection
A minimal, type-safe, decorator-free Dependency Injection container for TypeScript. No reflection. No decorators. No metadata. Just explicit code you can read top to bottom.
Explicit over magic
Every trade-off TinyDI makes is deliberate. Here is exactly what you get, stated plainly.
Zero Dependencies
No reflect-metadata, no decorators, no runtime library at all. `npm ls` on TinyDI shows nothing.
Type-Safe Tokens
`resolve(token)` infers the exact service type. No explicit generics, no `as` casts.
Singleton Support
The default lifetime. One instance, built once, reused for every resolution.
Transient Support
A fresh instance on every `resolve()` call, when that is genuinely what you need.
Framework Agnostic
Plain TypeScript. Works the same in Node.js, Bun, Deno, and the browser — Vue, React, Nuxt, or none at all.
Tiny Runtime
The whole container is a `Map` lookup and a function call. No startup cost to "discover" your graph.
How resolution actually works
No hidden step. A token identifies a service; the container looks up its registration and calls the factory, which resolves its own dependencies the same way.
Quick Start
This is the entire mental model. There is no step you are not seeing.
import { Container, createToken } from 'tinydi-container';
interface IGreeter {
greet(name: string): string;
}
class EnglishGreeter implements IGreeter {
greet(name: string): string {
return `Hello, ${name}!`;
}
}
const GreeterToken = createToken<IGreeter>('Greeter');
const container = new Container();
container.registerInstance(GreeterToken, new EnglishGreeter());
const greeter = container.resolve(GreeterToken); // typed as IGreeter
console.log(greeter.greet('TinyDI'));