redi
redi (pronounced ‘ready’) is a dependency injection library for TypeScript (and JavaScript), along with a set of bindings for React.
💡
1.0 release is out! Read the announcement.
Highlights
- Zero dependencies, lightweight and fast.
- No
emitDecoratorMetadata
required, works in both TypeScript and JavaScript. esbuild friendly. - Written in TypeScript with type definitions included.
- Runs on Node.js and browsers.
- Feature-rich:
- Injecting class instances
{ useClass: <ctor> }
, primitive values{ useValue: <value> }
, factories{ useFactory: <factoryFn> }
and aliases{ useExisting: <token> }
. - Injecting interfaces with
createIdentifier
. - Lazy instantiation with
{ useClass: <ctor>, lazy: true }
. - Async dependency with
{ useAsync: <Promise> }
,getAsync
andAsyncHook
. - Optional and multi-injection with
@Optional()
and@Many()
. - Hierarchical injectors with
@Self()
and@SkipSelf()
.
- Injecting class instances
- Provide hooks to integrate with React
useDependency(<token>)
. - Sufficiently tested with 100% code coverage.
Installation
Use your favorite package manager:
npm install @wendellhu/redi
Usage (TypeScript)
Enable experimental decorators in your tsconfig.json
:
{
"compilerOptions": {
+ "experimentalDecorators": true,
}
}
Then you can use decorators to define dependencies:
import { Inject } from '@wendellhu/redi';
class AuthService {
public getCurrentUserInfo(): UserInfo {}
}
class FileListService {
constructor(@Inject(AuthService) private readonly authService: AuthService) {}
public getUserFiles(): Promise<Files> {
const currentUser = this.authService.getCurrentUserInfo();
}
}
Register the services in an injector and retrieve them:
import { Injector } from '@wendellhu/redi';
const injector = new Injector([[AuthService], [FileListService]]);
injector.get(AuthService);
With React
Near the root of your React application, you can connect the dependencies to the React context using connectDependencies
:
import { connectDependencies } from '@wendellhu/redi/react';
import React from 'react';
import { PlatformService } from './services/PlatformService';
const App = connectDependencies(() => {
// ...
}, [[PlatformService]]);
In your child components, you can use the useDependency
hook to access them:
import { useDependency } from '@wendellhu/redi';
import React from 'react';
import { PlatformService } from './services/PlatformService';
const MyComponent: React.FC = () => {
const platformService = useDependency(PlatformService);
// ...
};
Links
- Documentation
- Demo TodoMVC, and its source code
- Scaffold to quickly start a new project with redi
Who is using?
- Univer
- ByteDance
Contributing
Please read the contributing guide for details on how to contribute to this project.
License
MIT. Copyright 2021-present Wenzhao Hu.