npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@apihub24/ts_dependency_injection

v0.4.0-alpha.0

Published

[![npm version](https://badge.fury.io/js/@apihub24%2Fts_dependency_injection.svg?icon=si%3Anpm)](https://badge.fury.io/js/@apihub24%2Fts_dependency_injection) [![License: Apache2.0](https://img.shields.io/badge/License-Apache2.0-green.svg)](https://opens

Readme

npm version License: Apache2.0 CI Codecov

Typescript Dependency Injection

This project provides a lightweight and flexible dependency injection (DI) container for TypeScript applications. It simplifies the management of class dependencies, making your code more modular, testable, and maintainable. The container supports transient services, singletons, and constructor-based dependency resolution.

Features

  • Dependency Resolution: Automatically resolves and injects class dependencies through the constructor.
  • Scoped Services: Register services under different keys to create distinct application contexts (e.g., global, test).
  • Singletons: Easily manage services that should only have one instance throughout their lifecycle.
  • Testing Support: The replaceWith function allows you to quickly mock dependencies for unit testing.
  • Minimalistic: A small and easy-to-understand codebase.

Installation

To use this container in your project, you'll need to install the reflect-metadata package, which is required for dependency resolution via decorators.

npm install --save @apihub24/ts_dependency_injection

Make sure to enable emitDecoratorMetadata and experimentalDecorators in your tsconfig.json file.

{
  "compilerOptions": {
    "target": "es2017",
    "module": "commonjs",
    "lib": ["es2017"],
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true
  }
}

Usage

  1. Registering Services

    Use the provided decorators to register your classes with the container.

Basic Service (Singleton)

A service creates a new instance every time it's injected when the instance not exists.

import { Service, inject } from "@apihub24/ts_dependency_injection";

// register a Singleton Logger
@Service()
class Logger {
  log(message: string) {
    console.log(message);
  }
}

// inject the Logger Instance
const logger = inject(Logger);

Abstraction to Implementation

Register a concrete implementation for an abstract class or interface. This is a common pattern for writing testable code.

import { ServiceFor, inject } from "@apihub24/ts_dependency_injection";

abstract class AuthService {
  abstract login(): void;
}

@ServiceFor(AuthService)
class BasicAuthService extends AuthService {
  login() {
    console.log("Logging in with basic authentication...");
  }
}

const authService = inject(AuthService);
authService.login();

Use Scoped Service

Pass some string to Scope the Service so you can have Multiple Instances of a Abstract Service. This can be used for Service Decorator also.

import { ServiceFor, inject, destroy } from "@apihub24/ts_dependency_injection";

abstract class AuthService {
  abstract login(): void;
}

@ServiceFor(AuthService, "1")
class AuthService1 extends AuthService {
  login() {
    console.log("Logging in with basic authentication...");
  }
}

@ServiceFor(AuthService, "2")
class AuthService2 extends AuthService {
  login() {
    console.log("Logging in with basic authentication...");
  }
}

const authService1 = inject(AuthService, "1");
const authService2 = inject(AuthService, "2");

// Be sure to Destroy the Instances when not used anymore!!!!
destroy(AuthService, "1");
destroy(AuthService, "2");
  1. Constructor Injection

    The container automatically resolves and provides dependencies to a class's constructor.

import { ServiceFor, inject } from "@apihub24/ts_dependency_injection";

@Service()
class Engine {}

@Service()
class Car {
  constructor(private engine: Engine) {}
}

const car = inject(Car);
console.log(car instanceof Car); // true
console.log(car.engine instanceof Engine); // true

If you want Inject a scoped Service use the @Inject Decorator.

import { ServiceFor, inject } from "@apihub24/ts_dependency_injection";

abstract class Engine {}
@ServiceFor(Engine, "petrol")
class PetrolEngine implements Engine {}
@ServiceFor(Engine, "electro")
class ElectroEngine implements Engine {}

@Service()
class ElectroCar {
  constructor(@Inject("electro") private engine: Engine) {}
}

@Service()
class PetrolCar {
  constructor(@Inject("petrol") private engine: Engine) {}
}

@Service()
class HybridCar {
  constructor(
    private electroEngine: ElectroEngine,
    private petrolEngine: PetrolEngine
  ) {}
}

const car1 = inject(ElectroCar);
const car2 = inject(PetrolCar);
const car3 = inject(HybridCar);

console.log(car1 instanceof ElectroCar); // true
console.log(car1.engine instanceof ElectroEngine); // true

console.log(car2 instanceof PetrolCar); // true
console.log(car2.engine instanceof PetrolEngine); // true

console.log(car3 instanceof ElectroCar); // true
console.log(car3.electroEngine instanceof ElectroEngine); // true
console.log(car3.petrolEngine instanceof PetrolEngine); // true
  1. Testing and Mocking

    Use replaceWith to substitute a dependency's implementation for testing purposes.

import { ServiceFor, inject } from "@apihub24/ts_dependency_injection";

// Production Service
abstract class DatabaseService {
  abstract query(): string;
}

@ServiceFor(DatabaseService)
class MySQLService extends DatabaseService {
  query() {
    return "Querying MySQL...";
  }
}

// A mock service for testing
class MockDatabaseService extends DatabaseService {
  query() {
    return "Mocking the database...";
  }
}

// In your test:
replaceWith(DatabaseService, MockDatabaseService);

const dbService = inject(DatabaseService);
console.log(dbService.query()); // "Mocking the database..."