{"id":10745,"library":"didi","title":"didi: Dependency Injection Container","description":"didi is a lightweight, battle-tested Inversion of Control (IoC) container for JavaScript and TypeScript, primarily used for dependency injection. It allows decoupling component declaration from instantiation by defining modules that declare components by name and specify how they are provided (e.g., as types, factories, or static values). The library then instantiates components on demand, transitively resolves their dependencies, and caches instances for reuse. Currently at stable version 11.0.0, didi maintains a moderate release cadence, largely driven by maintenance and dependency updates, with major version bumps often related to module system changes (e.g., ESM-only). Its key differentiators include its minimal footprint, focus on core DI patterns, and proven use in mature projects like Karma and diagram-js, making it suitable for applications requiring robust, explicit dependency management.","status":"active","version":"11.0.0","language":"javascript","source_language":"en","source_url":"git://github.com/nikku/didi","tags":["javascript","di","inversion of control","dependency","injection","injector","typescript"],"install":[{"cmd":"npm install didi","lang":"bash","label":"npm"},{"cmd":"yarn add didi","lang":"bash","label":"yarn"},{"cmd":"pnpm add didi","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"didi is ESM-only since v11.0.0. Use named imports for Injector.","wrong":"const Injector = require('didi');","symbol":"Injector","correct":"import { Injector } from 'didi';"},{"note":"Module is a type alias representing the structure of a didi module, not a runtime symbol to import. It's used for typing module definitions.","symbol":"Module","correct":"type Module = { [key: string]: any[] };"},{"note":"TypedDeclaration is a named export for advanced TypeScript usage, providing type hints for service declarations.","wrong":"import TypedDeclaration from 'didi';","symbol":"TypedDeclaration","correct":"import { TypedDeclaration } from 'didi';"}],"quickstart":{"code":"import { Injector } from 'didi';\n\ninterface Engine {\n  start(): void;\n}\n\nclass PetrolEngine implements Engine {\n  private power: number;\n  constructor(power: number) {\n    this.power = power;\n  }\n  start(): void {\n    console.log(`Starting petrol engine with ${this.power}hp`);\n  }\n}\n\nclass ElectricEngine implements Engine {\n  private voltage: number;\n  constructor(voltage: number) {\n    this.voltage = voltage;\n  }\n  start(): void {\n    console.log(`Starting electric engine with ${this.voltage}V`);\n  }\n}\n\nclass Car {\n  static $inject = ['engine', 'licensePlate'];\n  private engine: Engine;\n  private licensePlate: string;\n\n  constructor(engine: Engine, licensePlate: string) {\n    this.engine = engine;\n    this.licensePlate = licensePlate;\n  }\n\n  start() {\n    console.log(`Car with license ${this.licensePlate} is starting.`);\n    this.engine.start();\n  }\n}\n\nconst carModule = {\n  'engine': ['type', PetrolEngine],\n  'power': ['value', 150],\n  'licensePlate': ['value', 'XYZ-123']\n};\n\nconst electricCarModule = {\n  'engine': ['type', ElectricEngine],\n  'voltage': ['value', 400],\n  'licensePlate': ['value', 'EV-456']\n};\n\nconst petrolInjector = new Injector([carModule]);\nconst petrolCar = petrolInjector.get<Car>('car');\npetrolCar.start();\n\nconst electricInjector = new Injector([electricCarModule]);\nconst electricCar = electricInjector.get<Car>('car');\nelectricCar.start();\n\n// Example of invoking a function with injected dependencies\npetrolInjector.invoke(function(car: Car) {\n  console.log('\\nInvoking a function with injected car:');\n  car.start();\n});","lang":"typescript","description":"This quickstart demonstrates defining components, configuring modules with type, factory, and value providers, and retrieving typed instances using the Injector."},"warnings":[{"fix":"Migrate all imports from `require('didi')` to `import { ... } from 'didi';`. Ensure your project's build configuration supports ES Modules. For Node.js, this means using `'type': 'module'` in `package.json` or using `.mjs` file extensions.","message":"Version 11.0.0 drops support for CommonJS distribution. The package is now an ES module only.","severity":"breaking","affected_versions":">=11.0.0"},{"fix":"Ensure your Node.js environment is at version 20.12 or higher before upgrading to didi v11.x.","message":"Node.js engine requirement has been updated to `^20.12`.","severity":"breaking","affected_versions":">=11.0.0"},{"fix":"Always use the static `$inject` property on constructors/factories (e.g., `Car.$inject = ['engine', 'license']`) or the array notation (e.g., `['engine', 'Car', function(engine) {}]`) when targeting environments where code minification is applied to avoid issues.","message":"didi relies on argument names, function comments, or explicit `$inject` annotations for dependency resolution. Minification without proper configuration can break injection if not using `$inject` or array notation.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Change `const { Injector } = require('didi');` to `import { Injector } from 'didi';` and ensure your project is configured for ES modules.","cause":"Attempting to use `require('didi')` after upgrading to v11.0.0, which is ESM-only.","error":"TypeError: Injector is not a constructor"},{"fix":"Verify that 'dependencyName' is correctly defined in one of your didi modules using 'type', 'factory', or 'value' declaration. Check for typos in both the module definition and the injection point.","cause":"A component attempts to inject a dependency that has not been registered in any of the modules provided to the Injector.","error":"Error: No provider for 'dependencyName'! (Resolving: dependencyName)"},{"fix":"Ensure module definitions conform to `[ 'type' | 'factory' | 'value', ... ]` array structure. For example, `{'myService': ['type', MyService]}`.","cause":"Incorrect type signature when defining a didi module in TypeScript, often due to not using the array notation for providers.","error":"TS2345: Argument of type 'string' is not assignable to parameter of type 'any[]'."}],"ecosystem":"npm"}