@praha/diva is a lightweight, type-safe dependency injection library for TypeScript. It provides a simple API for managing dependencies through context-based providers.
npm install @praha/divaCreate a context using createContext() which returns a tuple of [Resolver, Provider]:
import { createContext } from '@praha/diva';
// Create a context
const [database, withDatabase] = createContext<Database>();
// Provide a value within a scope
withDatabase(() => new Database(), () => {
const db = database(); // Returns the Database instance
db.query('SELECT * FROM users');
});By default, providers cache the built value:
withDatabase(() => new Database(), () => {
const db1 = database(); // New instance created
const db2 = database(); // Same instance (cached)
console.log(db1 === db2); // true
});Use transient for a new instance on each resolution:
withDatabase.transient(() => new Database(), () => {
const db1 = database(); // New instance
const db2 = database(); // Different instance
console.log(db1 === db2); // false
});Providers support curried invocation for better reusability:
const [logger, withLogger] = createContext<Logger>();
// Create a reusable scoped function
const runWithLogger = withLogger(() => new ConsoleLogger());
runWithLogger(() => {
logger().info('Hello, world!');
});Create optional contexts that return undefined when not provided:
const [config, withConfig] = createContext<Config>({ required: false });
// Outside provider scope - returns undefined instead of throwing
const maybeConfig = config(); // undefinedUse withContexts() to compose multiple context providers:
import { createContext, withContexts } from '@praha/diva';
const [database, withDatabase] = createContext<Database>();
const [logger, withLogger] = createContext<Logger>();
const [auth, withAuth] = createContext<Auth>();
withContexts([
withDatabase(() => new Database()),
withLogger(() => new Logger()),
withAuth(() => new Auth()),
], () => {
// All contexts are available here
});Use mockContext from @praha/diva/test to inject mock values in tests:
import { createContext } from '@praha/diva';
import { mockContext } from '@praha/diva/test';
const [database, withDatabase] = createContext<Database>();
// Set up a scoped mock
mockContext(withDatabase, () => new MockDatabase());
// Now resolver returns mock without needing a provider
const db = database(); // Returns MockDatabase instance
// Transient mocks create new instances each time
mockContext.transient(withDatabase, () => new MockDatabase());
const db1 = database(); // New instance
const db2 = database(); // Different instanceContributions, issues and feature requests are welcome.
Feel free to check issues page if you want to contribute.
Copyright © PrAha, Inc.
This project is MIT licensed.