Awilix TypeScript: Complete DI Container Guide with Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Awilix for TypeScript: Complete DI Container Guide

Awilix is a powerful and flexible Dependency Injection (DI) container for Node.js and browsers, written in TypeScript. It provides an elegant way to manage dependencies in your application, making your code more modular, testable, and maintainable. In this article, we'll dive deep into using Awilix in TypeScript projects, from installation to advanced techniques.

1. What Is It and Why You Need It

In modern software development, the Inversion of Control (IoC) principle and Dependency Injection (DI) have become the de facto standard for building scalable and testable applications. Awilix is a DI container implementation that handles the creation and lifecycle management of objects (services, repositories, controllers, etc.). Instead of manually instantiating classes inside other classes (which leads to tight coupling), you register your dependencies with the container, and it automatically "injects" them where needed.

Why is this useful? First, it dramatically simplifies testing. You can easily swap a real implementation (e.g., a database) with a mock object during unit tests by simply registering a different dependency in the container. Second, it improves application architecture by enforcing the Single Responsibility Principle (SRP) and making dependencies explicit. Third, Awilix supports various object lifetimes (singleton, transient, scoped), giving you flexible control over memory and state management.

Awilix is particularly well-suited for TypeScript thanks to its strong typing. It provides built-in types for registering and resolving dependencies, allowing you to catch errors at compile time rather than at runtime. The library supports asynchronous dependency resolution, working with classes, factory functions, and existing object instances.

2. Installation

To install Awilix in your TypeScript project, run the following command in your terminal:

npm install awilix

Awilix has built-in TypeScript support, so you don't need to install separate type packages (@types/awilix). All types are included in the main library.

3. Quick Start — Minimal Working Example

Let's create a simple application that greets a user. We'll have a Greeter class that depends on a Logger.

import { createContainer, asClass, Lifetime } from 'awilix';

// 1. Define dependencies
class Logger {
  log(message: string): void {
    console.log(`[LOG]: ${message}`);
  }
}

class Greeter {
  private logger: Logger;

  // Dependency will be injected via constructor
  constructor({ logger }: { logger: Logger }) {
    this.logger = logger;
  }

  greet(name: string): void {
    this.logger.log(`Hello, ${name}!`);
  }
}

// 2. Create the container
const container = createContainer();

// 3. Register dependencies
container.register({
  logger: asClass(Logger, { lifetime: Lifetime.SINGLETON }),
  greeter: asClass(Greeter, { lifetime: Lifetime.TRANSIENT }),
});

// 4. Resolve (get) a Greeter instance
const greeter = container.resolve<Greeter>('greeter');

// 5. Use it
greeter.greet('World'); // Output: [LOG]: Hello, World!

In this example, we created a container, registered two classes (Logger as a singleton and Greeter as a transient object), and then resolved Greeter. Awilix automatically created a Logger instance and passed it to the Greeter constructor.

4. Key Methods/Functions/Classes

Let's explore the core Awilix API. For each method, we provide the signature, description, and an example.

4.1. createContainer()

Signature:

Recommendations