injection-js
Dependency injection library for JavaScript and TypeScript in 5.1K. It is an extraction of the Angular's ReflectiveInjector which means that it's well designed, feature complete, fast, reliable and well tested.
Top Related Projects
A powerful and lightweight inversion of control container for JavaScript & Node.js apps powered by TypeScript.
Lightweight dependency injection container for JavaScript/TypeScript
Simple yet powerful dependency injection tool for JavaScript and TypeScript.
A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications with TypeScript/JavaScript 🚀
Quick Overview
Injection-js is a lightweight dependency injection library for JavaScript and TypeScript. It is extracted from Angular's dependency injection system, providing a standalone solution for managing dependencies in JavaScript applications without the need for the full Angular framework.
Pros
- Lightweight and standalone, with no external dependencies
- Compatible with both JavaScript and TypeScript
- Follows Angular's dependency injection patterns, making it familiar for Angular developers
- Supports hierarchical injectors and various injection techniques
Cons
- Limited documentation compared to more established DI libraries
- May have a steeper learning curve for developers not familiar with Angular's DI system
- Less active community and fewer resources compared to more popular alternatives
- Might be overkill for small projects or simple use cases
Code Examples
- Basic dependency injection:
import { ReflectiveInjector, Injectable } from 'injection-js';
@Injectable()
class Engine {
start() {
console.log('Engine started');
}
}
@Injectable()
class Car {
constructor(private engine: Engine) {}
start() {
this.engine.start();
console.log('Car started');
}
}
const injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
const car = injector.get(Car);
car.start();
- Using providers:
import { ReflectiveInjector, Injectable, Inject } from 'injection-js';
@Injectable()
class Logger {
log(message: string) {
console.log(message);
}
}
const GREETING = 'greeting';
@Injectable()
class Greeter {
constructor(
private logger: Logger,
@Inject(GREETING) private greeting: string
) {}
greet(name: string) {
this.logger.log(`${this.greeting}, ${name}!`);
}
}
const injector = ReflectiveInjector.resolveAndCreate([
Logger,
Greeter,
{ provide: GREETING, useValue: 'Hello' }
]);
const greeter = injector.get(Greeter);
greeter.greet('World');
- Hierarchical injectors:
import { ReflectiveInjector, Injectable } from 'injection-js';
@Injectable()
class Service {
getValue() {
return 'Service Value';
}
}
@Injectable()
class Component {
constructor(private service: Service) {}
display() {
console.log(this.service.getValue());
}
}
const parentInjector = ReflectiveInjector.resolveAndCreate([Service]);
const childInjector = parentInjector.resolveAndCreateChild([Component]);
const component = childInjector.get(Component);
component.display();
Getting Started
To use injection-js in your project:
-
Install the package:
npm install injection-js reflect-metadata
-
Import and use in your TypeScript file:
import 'reflect-metadata'; import { ReflectiveInjector, Injectable } from 'injection-js'; @Injectable() class MyService { // Service implementation } @Injectable() class MyComponent { constructor(private service: MyService) {} // Component implementation } const injector = ReflectiveInjector.resolveAndCreate([MyService, MyComponent]); const component = injector.get(MyComponent);
Remember to enable experimental decorators and emit decorator metadata in your TypeScript configuration.
Competitor Comparisons
A powerful and lightweight inversion of control container for JavaScript & Node.js apps powered by TypeScript.
Pros of InversifyJS
- More feature-rich with advanced concepts like tagged bindings and contextual bindings
- Extensive documentation and community support
- Better TypeScript integration with decorators and metadata reflection
Cons of InversifyJS
- Steeper learning curve due to more complex API
- Slightly larger bundle size
- Requires additional setup and configuration
Code Comparison
injection-js:
import { ReflectiveInjector } from 'injection-js';
@Injectable()
class Service {}
const injector = ReflectiveInjector.resolveAndCreate([Service]);
const service = injector.get(Service);
InversifyJS:
import { Container, injectable, inject } from 'inversify';
@injectable()
class Service {}
const container = new Container();
container.bind<Service>(Service).toSelf();
const service = container.get<Service>(Service);
Both libraries provide dependency injection for TypeScript and JavaScript applications. injection-js is lighter and easier to set up, making it suitable for smaller projects or those transitioning from Angular. InversifyJS offers more advanced features and better TypeScript integration, making it a good choice for larger, more complex applications that require fine-grained control over dependency injection. The code comparison shows that InversifyJS requires more setup but provides a more explicit binding process.
Lightweight dependency injection container for JavaScript/TypeScript
Pros of TSyringe
- Actively maintained with more recent updates
- Broader ecosystem integration (works well with other Microsoft tools)
- More comprehensive documentation and examples
Cons of TSyringe
- Steeper learning curve for beginners
- Larger bundle size
- Less flexible configuration options
Code Comparison
injection-js:
import { ReflectiveInjector } from 'injection-js';
class Engine {}
class Car {
constructor(public engine: Engine) {}
}
const injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
const car = injector.get(Car);
TSyringe:
import { injectable, container } from "tsyringe";
@injectable()
class Engine {}
@injectable()
class Car {
constructor(public engine: Engine) {}
}
const car = container.resolve(Car);
Both libraries provide dependency injection for TypeScript projects, but TSyringe uses decorators and a global container, while injection-js uses a more explicit injector creation approach. TSyringe's syntax is slightly more concise, but injection-js offers more control over injector creation and configuration.
TSyringe is better suited for larger projects with complex dependency graphs, while injection-js might be preferable for smaller projects or those requiring more fine-grained control over injection behavior.
Simple yet powerful dependency injection tool for JavaScript and TypeScript.
Pros of TypeDI
- More active development and maintenance
- Better TypeScript support with decorators
- Simpler API for container management
Cons of TypeDI
- Larger bundle size
- Steeper learning curve for beginners
- Less Angular-like syntax
Code Comparison
TypeDI:
import { Container, Service } from 'typedi';
@Service()
class ExampleService {
doSomething() {
return 'Hello, TypeDI!';
}
}
const instance = Container.get(ExampleService);
injection-js:
import { ReflectiveInjector } from 'injection-js';
class ExampleService {
doSomething() {
return 'Hello, injection-js!';
}
}
const injector = ReflectiveInjector.resolveAndCreate([ExampleService]);
const instance = injector.get(ExampleService);
Summary
TypeDI and injection-js are both dependency injection libraries for TypeScript and JavaScript. TypeDI offers more modern TypeScript features and active development, while injection-js provides a more Angular-like experience with a smaller footprint. TypeDI's API is generally simpler, but it may have a steeper learning curve for those unfamiliar with decorators. injection-js might be preferred for Angular developers or projects requiring a smaller bundle size. The choice between the two depends on specific project requirements and developer preferences.
A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications with TypeScript/JavaScript 🚀
Pros of Nest
- Full-featured framework with built-in support for various architectural patterns
- Extensive ecosystem with modules for databases, authentication, and more
- Strong TypeScript support and decorators for enhanced developer experience
Cons of Nest
- Steeper learning curve due to its comprehensive nature
- Potentially overkill for smaller projects or microservices
- Opinionated structure may limit flexibility in some cases
Code Comparison
Nest:
@Injectable()
export class CatsService {
private readonly cats: Cat[] = [];
create(cat: Cat) {
this.cats.push(cat);
}
findAll(): Cat[] {
return this.cats;
}
}
injection-js:
import { Injectable } from 'injection-js';
@Injectable()
export class CatsService {
private readonly cats: Cat[] = [];
create(cat: Cat) {
this.cats.push(cat);
}
findAll(): Cat[] {
return this.cats;
}
}
The code structure is similar, but Nest provides additional decorators and features beyond basic dependency injection.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Dependency Injection
Dependency injection library for JavaScript and TypeScript in 5.2K. It is an extraction of the Angular's dependency injection which means that it's feature complete, fast, reliable and well tested.
Why not Angular version 5 and above?
Angular version 5 deprecated the ReflectiveInjector
API and introduced StaticInjector
. In short, the dependency injection in the newest versions of Angular will happen entirely compile-time so reflection will not be necessary.
However, if you want to use dependency injection in your Node.js, Vue, React, Vanilla JS, TypeScript, etc. application you won't be able to take advantage of StaticInjector
the way that Angular will because your application won't be compatible with Angular compiler.
This means that if you need dependency injection outside of Angular @angular/core
is not an option. In such case, use injection-js
for fast, small, reliable, high-quality, well designed and well tested solution.
How to use?
$ npm i injection-js
# OR
$ yarn add injection-js
Note:
For ES5
Class
syntax and TypeScript you need a polyfill for the Reflect API. You can use:
- reflection (only 3kb ð¥)
- reflect-metadata
- core-js (
core-js/es7/reflect
)Also for TypeScript you will need to enable
experimentalDecorators
andemitDecoratorMetadata
flags within yourtsconfig.json
TypeScript
import 'reflect-metadata';
import { ReflectiveInjector, Injectable, Injector } from 'injection-js';
class Http {}
@Injectable()
class Service {
constructor(private http: Http) {}
}
@Injectable()
class Service2 {
constructor(private injector: Injector) {}
getService(): void {
console.log(this.injector.get(Service) instanceof Service);
}
createChildInjector(): void {
const childInjector = ReflectiveInjector.resolveAndCreate([Service], this.injector);
}
}
const injector = ReflectiveInjector.resolveAndCreate([Service, Http]);
console.log(injector.get(Service) instanceof Service);
ES6
const { Inject, ReflectiveInjector } = require('injection-js');
class Http {}
class Service {
static get parameters() {
return [new Inject(Http)];
}
constructor(http) {
this.http = http;
}
}
const injector = ReflectiveInjector.resolveAndCreate([Http, Service]);
console.log(injector.get(Service) instanceof Service);
ES5
require('reflect-metadata');
var di = require('injection-js');
var Http = di.Class({
constructor: function() {},
});
var Service = di.Class({
constructor: [
Http,
function(http) {
this.http = http;
},
],
});
var injector = di.ReflectiveInjector.resolveAndCreate([Http, Service]);
console.log(injector.get(Service) instanceof Service);
API
For full documentation check Angular DI docs:
Ecosystem
This is a list of libraries that are using injection-js. If you have a suggestion on what to add, please don't hesitate to submit a PR.
Libraries
- ng-packagr Transpile your libraries to Angular Package Format. Part of the official Angular CLI.
- @martin_hotell/axios-http Injectable axios HttpClient wrapper for browser and node
- @martin_hotell/rea-di Dependency injection for React done right. Hierarchical injection on both component and service layer powered by injection-js (Angular DI framework) ð
- rxstack RxStack is a realtime object-oriented framework which helps you build a micro service web applications on top of other frameworks like express and socketio by adding an abstraction layer.
- ServeRX-ts Experimental Node.js HTTP framework using RxJS, built with TypeScript and optimized for serverless deployments. Features declarative routes and dependency injection powered by injection-js.
License
MIT
Top Related Projects
A powerful and lightweight inversion of control container for JavaScript & Node.js apps powered by TypeScript.
Lightweight dependency injection container for JavaScript/TypeScript
Simple yet powerful dependency injection tool for JavaScript and TypeScript.
A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications with TypeScript/JavaScript 🚀
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot