Dependency injection
without the boilerplate

A lightweight wrapper over InversifyJS 8. Register a class once, inject it as a property with a single decorator — IDs are derived from your class names automatically. No manual symbols, no binding ceremony.

$ npm install inversify-props
npm version npm downloads license

Vue · Lit · vanilla TypeScript — framework-agnostic by design

Three steps, zero ceremony

Define, register, inject. IDs are inferred from class and property names.

services.ts
// 1. Define a class + interface
interface IService1 {
  method1(): string;
}

class Service1 implements IService1 {
  method1() {
    return 'method 1';
  }
}
main.ts
import { container } from 'inversify-props';

// 2. Register it once
container.addSingleton<IService1>(Service1);
component.ts
import { cid, container, inject } from 'inversify-props';

// 3. Inject it anywhere — the ID comes from the property name
class MyComponent {
  @inject() service1!: IService1;
}

// ...or resolve directly
const service1 = container.get<IService1>(cid.IService1);

Why not plain InversifyJS?

Plain InversifyJS makes you manage service identifiers and write fluent bindings by hand. inversify-props derives everything from names.

plain inversify
const TYPES = {
  Service1: Symbol.for('Service1'),
};

container
  .bind<IService1>(TYPES.Service1)
  .to(Service1)
  .inSingletonScope();

class MyComponent {
  @inject(TYPES.Service1)
  private service1: IService1;
}
inversify-props
container.addSingleton<IService1>(Service1);

class MyComponent {
  @inject() service1!: IService1;
}

Three lifetimes

addSingleton

One shared instance for the whole app. The most common choice for services.

addTransient

A fresh instance every time the dependency is resolved.

addRequest

One instance per request scope — shared within a single resolution tree.

Core API

container

The shared container instance.

container.addSingleton<T>(Class, id?)

Register a class with singleton lifetime.

container.addTransient<T>(Class, id?)

New instance per resolve.

container.addRequest<T>(Class, id?)

One instance per request scope.

@inject() / @Inject()

Property or constructor-parameter decorator. IDs inferred from names — camelCase, PascalCase, and leading _ all handled.

cid

Generated cache of IDs, e.g. cid.IService1.

mockSingleton / mockTransient / mockRequest

Swap real implementations for mocks in tests.

resetContainer()

Clear all bindings — clean state between tests.

TypeScript setup

Decorators need a couple of compiler options. No separate reflect-metadata install required — ESM and CommonJS builds ship in the box.

tsconfig.json
{
  "compilerOptions": {
    "target": "es2020",
    "lib": ["es2020", "dom"],
    "moduleResolution": "bundler",
    "experimentalDecorators": true,
    "useDefineForClassFields": false
  }
}

Get started

$ npm install inversify-props

Requires Node.js 20.19+ · TypeScript with decorators · MIT licensed