Skip to content

A lightweight, type-safe dependency injection container for anything, inspired by Angular's DI system

Notifications You must be signed in to change notification settings

git-illuma/core

Repository files navigation

Illuma – Dependency Injection for TypeScript

NPM Version NPM Downloads npm bundle size Test coverage

A universal, lightweight and type-safe dependency injection container for TypeScript. Heavily inspired by Angular's DI system, but designed to work in any environment (Node.js, Bun, Deno, browsers, and more).

Features

  • Type-Safe – Excellent type inference
  • Lightweight – Zero dependencies, minimal bundle size
  • Flexible – Classes, factories, values, and aliases
  • Optional decorators – Injectable classes with @NodeInjectable() decorator
  • Multi-Tokens – Built-in multi-provider support
  • Plugin System – Extensible architecture with custom middlewares, scanners, and diagnostics
  • TestKit – Unit testing and mocking utilities for any testing framework
  • Universal – Node.js, Bun, Deno, browser, and Electron

Installation

npm install @illuma/core

Compatibility

Compatible with virtually anything supporting ES2015+ (ES6+). Practically the library is compatible with Node.js (v14+), Bun, Deno and all modern browsers. For older environments, consider using a transpiler or provide polyfills as needed.

Quick start

import { NodeContainer, NodeInjectable, nodeInject } from '@illuma/core';

@NodeInjectable()
class Logger {
  public log(message: string) {
    console.log(`[LOG]: ${message}`);
  }
}

@NodeInjectable()
class UserService {
  private readonly logger = nodeInject(Logger);

  public getUser(id: string) {
    this.logger.log(`Fetching user ${id}`);
    return { id, name: 'John Doe' };
  }
}

const container = new NodeContainer();
container.provide([Logger, UserService]);
container.bootstrap();

const userService = container.get(UserService);

Note: Example above requires experimentalDecorators and emitDecoratorMetadata in tsconfig. See Getting Started for decorator-free alternatives.

Using Tokens

import { NodeToken, MultiNodeToken, NodeContainer } from '@illuma/core';

// Single-value token
const CONFIG = new NodeToken<{ apiUrl: string }>('CONFIG');

// Multi-value token (when injected, returns array)
const PLUGINS = new MultiNodeToken<Plugin>('PLUGINS');

const container = new NodeContainer();

container.provide([
  // Equivalent to:
  // { provide: CONFIG, value: { apiUrl: 'https://api.example.com' } }
  CONFIG.withValue({ apiUrl: 'https://api.example.com' }),

  // Equivalent to:
  // { provide: PLUGINS, useClass: AnalyticsPlugin }
  PLUGINS.withClass(AnalyticsPlugin),

  // Equivalent to:
  // { provide: PLUGINS, useClass: LoggingPlugin }
  PLUGINS.withClass(LoggingPlugin),
]);

container.bootstrap();

const config = container.get(CONFIG);    // { apiUrl: string }
const plugins = container.get(PLUGINS);  // Plugin[]: [AnalyticsPlugin, LoggingPlugin]

See Tokens Guide for more details.

Provider types

// Class provider
container.provide(MyService);

// Value provider
container.provide({ provide: CONFIG, value: { apiUrl: '...' } });

// Factory provider
container.provide({ provide: DATABASE, factory: () => {
  // You can use nodeInject inside factories!
  const env = nodeInject(ENV);
  return createDatabase(env.connectionString);
} });

// Class provider with custom implementation
container.provide({ provide: DATABASE, useClass: DatabaseImplementation });

// Alias provider
container.provide({ provide: Database, alias: ExistingDatabase });

See Providers Guide for details.

Testing

import { createTestFactory } from '@illuma/core/testkit';

const createTest = createTestFactory({
  target: UserService,
  provide: [{ provide: Logger, useClass: MockLogger }],
});

it('should fetch user', () => {
  const { instance } = createTest();
  expect(instance.getUser('123')).toBeDefined();
});

See Testing Guide for examples.

Documentation

Guide Description
Getting Started Installation, setup, and basic usage
Providers Value, factory, class, and alias providers
Tokens NodeToken and MultiNodeToken
Async Injection Lazy loading and sub-containers
Testing TestKit and mocking
Plugins Extending Illuma with custom scanners and diagnostics
Technical Overview Deep dive into how Illuma works
API Reference Complete API documentation
Troubleshooting Error codes and solutions

Plugins

Illuma supports plugins! Check these out:

  • @illuma/reflect – Constructor metadata and property decorator injection support

See Plugins Guide for creating your own plugins.

Contributing

Thank you for considering contributing to Illuma! I deeply appreciate your interest in making this project better.

Anyways, to get you started, please take a look at the Contributing Guide for guidelines on how to setup development environment, run tests, and submit pull requests.

License

MIT

Created by bebrasmell

Links