InversifyJS is a robust and lightweight Inversion of Control (IoC) container for JavaScript and TypeScript applications, currently at version 8.1.0. It facilitates Dependency Injection (DI) by using decorators and TypeScript's reflection capabilities to manage the instantiation and injection of dependencies, promoting adherence to SOLID principles, good OOP, and IoC practices. The library is actively maintained with frequent minor and patch releases across its core and ecosystem packages, addressing new features and bug fixes. Key differentiators include its strong TypeScript integration, minimal runtime overhead, and a developer-friendly API designed to enhance modularity, testability, and maintainability. InversifyJS emphasizes a explicit dependency graph, helping developers build scalable applications by reducing coupling between components. It relies heavily on `reflect-metadata` for design-time type information, which is a fundamental aspect of its operation.
npm install inversifyVerified import paths — ran on the pinned version, not inferred.
This quickstart demonstrates the core concepts of InversifyJS: defining interfaces, using symbols for binding identifiers, marking classes with `@injectable`, injecting dependencies with `@inject`, configuring the `Container` with `bind().to()`, and finally resolving an instance using `container.get()`. It highlights the necessary `reflect-metadata` import.
Review all container API calls. Replace `await container.load(module)` with `container.loadAsync(module)` if asynchronous behavior is needed, or simply `container.load(module)` if synchronous is desired (which is now the default). Apply similar changes for `unbind`, `rebind`, `unload`, and `unbindAll`.
Upgrade to Node.js 20.19.0+ or 22+. If sticking with older Node.js, replace `require('inversify')` with `import('inversify')` for async loading or transition your project to native ESM.For classes with `protected` or `private` constructors used as identifiers, switch to `Symbol.for()` or a custom symbol as the service identifier. For typical class-based identifiers, no change is needed.
Migrate any `toProvider` bindings to `toFactory` bindings, utilizing the `Factory` type.
Ensure `reflect-metadata` is installed and the `import 'reflect-metadata';` statement is the first line in your main application file. Also, configure `tsconfig.json` with `"experimentalDecorators": true`, `"emitDecoratorMetadata": true`, and `"target": "ES2022"` or later.
For injection inheritance, use the `@injectFromBase` decorator. If you relied on custom metadata or middlewares, you may need to reconsider your approach or implement similar functionality manually.
Add `import 'reflect-metadata';` as the very first line of your application's entry file. Ensure `reflect-metadata` is installed as a dependency. Check `tsconfig.json` for `"emitDecoratorMetadata": true` and `"experimentalDecorators": true`.
Ensure `container.bind<T>(TYPES.MyService).to(MyServiceImpl);` is called before attempting to `container.get<T>(TYPES.MyService);`. Double-check the `ServiceIdentifier` used in `bind` and `get` matches exactly.
Identify the circular dependency. Strategies to resolve include: refactoring to break the cycle, using an initializer method (`@postConstruct`), using `toDynamicValue` or `toFactory` for lazy loading, or introducing an intermediate interface/abstraction.
Add `import { Container } from 'inversify';` to the top of your file. If using CommonJS in an environment that doesn't support `require(esm)` (e.g., Node.js < 20.19.0), you might need to use dynamic imports or transpile your code to a compatible module format.