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 🙏

© 2025 – Pkg Stats / Ryan Hefner

jeringa

v1.0.0-20250226115528.commit-9b7214f

Published

A lightweight, reflection-based dependency injection library for TypeScript.

Downloads

679

Readme

Jeringa

A lightweight, reflection-based dependency injection library for TypeScript.

Installation

npm install jeringa

Features

  • Type-safe dependency injection using TypeScript decorators and metadata reflection
  • Automatic resolution of dependency graphs
  • Support for named dependencies with @InjectByName
  • Cycle detection in dependency graphs
  • Compatible with class inheritance and complex class hierarchies
  • Visualization of dependency graphs with GraphViz

Requirements

  • TypeScript 4.x or higher
  • reflect-metadata for type information
  • Enable experimentalDecorators and emitDecoratorMetadata in your tsconfig.json
{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

Basic Usage

import { Inject, injectDependencies } from 'jeringa';
import 'reflect-metadata';

// Define your classes with the @Inject decorator
@Inject
class Database {
  connect() {
    return 'Connected to database';
  }
}

@Inject
class UserService {
  constructor(private db: Database) {}
  
  getUsers() {
    this.db.connect();
    return ['User1', 'User2'];
  }
}

@Inject
class Application {
  constructor(private userService: UserService) {}
  
  run() {
    return this.userService.getUsers();
  }
}

// Bootstrap your application
async function bootstrap() {
  const app = await injectDependencies(Application);
  console.log(app.run()); // ['User1', 'User2']
}

bootstrap();

Named Dependencies

Use @InjectByName when you need to inject dependencies by name:

import { Inject, InjectByName, injectDependencies } from 'jeringa';

@Inject
class ConfiguredService {
  constructor(
    @InjectByName('config') private config: any
  ) {}
  
  getApiKey() {
    return this.config.apiKey;
  }
}

@Inject
class Application {
  constructor(private service: ConfiguredService) {}
  
  run() {
    return this.service.getApiKey();
  }
}

// Provide named dependencies when bootstrapping
async function bootstrap() {
  const app = await injectDependencies(Application, {
    config: { apiKey: 'secret-key-123' }
  });
  
  console.log(app.run()); // 'secret-key-123'
}

bootstrap();

Working with Inheritance

Jeringa correctly handles inheritance chains:

@Inject
class BaseService {
  constructor(@InjectByName('logger') protected logger: any) {}
  
  log(message: string) {
    this.logger.info(message);
  }
}

@Inject
class ExtendedService extends BaseService {
  // Inherits the constructor and its injections
  
  logExtended(message: string) {
    this.log(`Extended: ${message}`);
  }
}

// The logger dependency will be properly injected into ExtendedService
const service = await injectDependencies(ExtendedService, {
  logger: { info: console.log }
});

Visualizing Dependency Graphs

Jeringa provides a utility to generate GraphViz visualizations of your dependency graph:

import { createDependencyGraph, getGraphViz } from 'jeringa';

const graph = createDependencyGraph(Application);
const dotGraph = getGraphViz(graph);

// Output the DOT format string to visualize with GraphViz tools
console.log(dotGraph);

API Reference

Decorators

  • @Inject: Class decorator to mark a class as injectable
  • @InjectByName(name: string): Parameter decorator to inject dependencies by name

Functions

  • injectDependencies<T>(ctor: Constructor<T>, providedDependenciesByName?: Record<string, any>): Promise<T> Bootstrap your application by creating an instance of the specified class with all dependencies resolved

  • createDependencyGraph(ctor: Constructor): DependencyGraph Create a dependency graph for analysis or visualization

  • getGraphViz(graph: DependencyGraph): string Generate a GraphViz DOT format representation of the dependency graph

Error Handling

Jeringa provides helpful error messages for common issues:

  • Circular dependencies
  • Missing named dependencies
  • Missing type information (when decorators or metadata are not properly configured)