Skip to content

@nodelibraries/iocType-Safe IoC Container

Seamless dependency injection for Node.js, TypeScript and JavaScript. Clean, fully type-safe with zero external libraries and no decorators required. Inspired by .NET Core's DI system.

Quick Start

bash
npm install @nodelibraries/ioc
typescript
import { ServiceCollection, ServiceProvider } from '@nodelibraries/ioc';

// Define interfaces
interface ILogger {
  log(message: string): void;
}

interface IUserService {
  getUsers(): string[];
}

// Implementations
class Logger implements ILogger {
  log(message: string) {
    console.log(`[LOG] ${message}`);
  }
}

class UserService implements IUserService {
  constructor(private logger: ILogger) {}

  getUsers(): string[] {
    this.logger.log('Fetching users...');
    return ['Alice', 'Bob'];
  }
}

// Register services
const services = new ServiceCollection();
const ILoggerToken = Symbol('ILogger');
const IUserServiceToken = Symbol('IUserService');

// ⚠️ IMPORTANT: If a class constructor has parameters (dependencies), you MUST provide them in the dependencies array,
// and dependencies must appear in the array in the exact same order as the constructor parameters.
services.addSingleton<ILogger>(ILoggerToken, Logger); // No dependencies - constructor has no parameters

services.addScoped<IUserService>(IUserServiceToken, UserService, [ILoggerToken]); // Has dependency - MUST provide [ILoggerToken]

// Build provider
const provider = services.buildServiceProvider();

// Use services
const scope = provider.createScope();
const userService = await scope.getRequiredService<IUserService>(IUserServiceToken);
const users = userService.getUsers();

Why @nodelibraries/ioc?

@nodelibraries/ioc is a production-ready, type-safe IoC container designed for Node.js and TypeScript, inspired by .NET Core's dependency injection system. Seamlessly inject dependencies into your application with zero dependencies and no decorators required.

Learn more about our philosophy and design principles in the About guide.

🎯 Clean & Simple

No decorators, no annotations, no framework lock-in. Your code remains pure and framework-agnostic.

typescript
// Clean, simple registration
// ⚠️ IMPORTANT: If a class constructor has parameters (dependencies), you MUST provide them in the dependencies array
services.addSingleton<ILogger>(ILoggerToken, Logger); // No dependencies - constructor has no parameters
services.addScoped<IUserService>(IUserServiceToken, UserService, [ILoggerToken]); // Has dependency - MUST provide [ILoggerToken]

🔒 Type-Safe by Design

Built from the ground up for TypeScript. Full type inference, autocomplete, and compile-time safety.

typescript
// Full type safety with autocomplete
const logger = await provider.getRequiredService<ILogger>(ILoggerToken);
logger.log('Hello'); // ✅ TypeScript knows this method exists

🚀 Production Ready

Battle-tested features including scope validation, lifecycle hooks, and comprehensive error handling.

typescript
// Build with validation (recommended for development)
const provider = services.buildServiceProvider({
  validateScopes: true, // Catch lifetime mismatches (e.g., scoped service in singleton)
  validateOnBuild: true, // Validate all dependencies exist at build time
});

Note: Both options default to false. Enable them explicitly for validation. For detailed explanations, examples, and .NET Core comparison, see the Scope Validation Guide.

🔄 Enhanced Circular Dependency Support

Circular dependencies are automatically resolved for all service lifetimes, including Transient services (which .NET Core doesn't support).

typescript
// Circular dependencies work seamlessly
class ServiceA {
  constructor(private serviceB: ServiceB) {}
}

class ServiceB {
  constructor(private serviceA: ServiceA) {} // ✅ Works!
}

🎨 Flexible Registration

Register services using:

  • Concrete classes - Direct class registration
  • Abstract interfaces - Interface-based registration with tokens
  • Factory functions - Complex initialization logic
  • Pre-created values - JSON objects, primitives, instances

Installation

bash
npm install @nodelibraries/ioc

No additional configuration required! The library has zero dependencies and works out of the box.

Support

If you find this project helpful, consider supporting it:

Next Steps

Released under the ISC License. If you find this project helpful, consider buying me a coffee