tsyringe Alternative for TypeScript Dependency Injection

ts-ioc-container is a fast, lightweight TypeScript dependency injection container for teams that like the simplicity of decorator-based DI but need more control over scopes, providers, tokens, lifecycle hooks, and custom injection strategies.

tsyringe is a good fit when an application mainly needs constructor injection and singleton/transient lifetimes. ts-ioc-container is designed for projects that also need request scopes, page scopes, provider pipelines, explicit tokens, aliases, lazy dependencies, lifecycle hooks, and customization points around how objects are created.

Needts-ioc-container fit
Fast TypeScript dependency resolutionLightweight runtime with executable benchmark coverage against tsyringe
Request or transaction scopesTagged child containers and scoped registration rules
Decorator-based injection@register, @inject, @onConstruct, @onDispose, and metadata utilities
Explicit dependency tokensClass, key, alias, function, constant, lazy, and grouped token shapes
Custom factoriesProvider APIs for values, classes, factories, arguments, singletons, visibility, and decoration
Lifecycle cleanupDisposable scopes and onDispose hooks
Framework integrationRecipes for Express.js, Fastify, Next.js, React, and SolidJS
Custom behaviorPluggable injectors, provider pipes, registration pipes, and custom hooks

Scoped containers make it practical to isolate per-request, per-transaction, per-page, or per-widget state while sharing application-wide services from a parent container.

TypeScript
const app = new Container({ tags: ['application'] });

function handleRequest() {
const request = app.createScope({ tags: ['request'] });
try {
  return request.resolve('RequestHandler').handle();
} finally {
  request.dispose();
}
}
const app = new Container({ tags: ['application'] });

function handleRequest() {
const request = app.createScope({ tags: ['request'] });
try {
  return request.resolve('RequestHandler').handle();
} finally {
  request.dispose();
}
}

Provider behavior is composable. You can cache instances, pass runtime arguments, decorate services, restrict visibility, expose aliases, or delay work until a dependency is actually needed.

The token API keeps dependency requests explicit and reusable. Use keys for interfaces, class tokens for constructors, aliases for alternate names, grouped aliases for plugin-like collections, and lazy tokens for deferred work.

Lifecycle hooks let services initialize after construction and clean up when a scope is disposed. That matters for request state, transactions, sockets, subscriptions, and any dependency that owns resources.

Choose tsyringe when your application only needs straightforward constructor injection, a familiar decorator API, and a small set of lifetime options.

Choose ts-ioc-container when dependency injection is part of the application architecture: request isolation, framework integration, lifecycle cleanup, provider customization, token composition, and testable product behavior all matter.

Continue with the Product Capabilities map or jump into Dependency and Scope.