Early alpha. Not production-ready, and APIs can change. Read the status

LongHorn

DI container

LongHorn's dependency injection container, @longhornjs/container, resolves services through typed tokens and keeps one instance of each per application. It uses plain functions, not decorators.

Register and resolve

import { Container, provide, token } from '@longhornjs/container'

const Clock = token<{ now(): number }>('clock')
const Greeting = token<{ stamp(): string }>('greeting')

const container = new Container()
container.register(provide(Clock, {
  factory: () => ({ now: () => Date.now() }),
}))
container.register(provide(Greeting, {
  deps: [Clock],
  factory: (clock) => ({ stamp: () => `at ${clock.now()}` }),
}))

// In a test, replace a dependency without touching the code that uses it.
container.override(provide(Clock, {
  factory: () => ({ now: () => 0 }),
}))
container.resolve(Greeting).stamp() // "at 0"

What it does

In a request

Each Longhorn app has a container at app.container. Route handlers reach it with c.get('container').

Guide: dependency injection.