@wyrly/core
v2.2.1
Published
Type-safe dependency injection for modern TypeScript without reflect-metadata
Maintainers
Readme
@wyrly/core
Type-safe dependency injection for modern TypeScript. No reflect-metadata, no
emitDecoratorMetadata, no parameter decorators.
Use @wyrly/core when you want explicit dependencies, typed tokens, standard decorators, request
scopes, and inspectable dependency graphs without framework lock-in.
Runtimes: Deno 2.x (JSR) · Node.js 20+ / Bun (npm)
Japanese: README.ja.md
When to choose Wyrly DI
- You want TypeScript DI that works with standard decorators instead of legacy decorator metadata.
- You want interface-based dependencies to stay type-safe through typed tokens.
- You need request scopes for Next.js, Hono, Express, Fresh, GraphQL, or another web runtime.
- You want to inspect and validate the dependency graph in CI.
- You prefer composition roots and explicit wiring for DDD / Clean Architecture.
Runtimes
| Runtime | Registry | Import |
| ------------ | ------------------------------------------------ | ------------------------ |
| Deno 2.x | JSR @wyrly/core | jsr:@wyrly/core@^2.0.0 |
| Node.js 20+ | npm | @wyrly/core |
| Bun | npm (same package) | @wyrly/core |
Published to JSR and npm from the same source. Deno users should prefer JSR; Node/Bun users use npm.
Install (Deno / JSR)
// deno.json
{
"imports": {
"@wyrly/core": "jsr:@wyrly/core@^2.0.0"
}
}# or add with Deno 2.x
deno add jsr:@wyrly/coreimport { createContainer, Injectable, token } from "@wyrly/core";See also on jsr.io/@wyrly/core.
Install (Node.js / Bun / npm)
npm install @wyrly/core
# bun add @wyrly/coreimport { createContainer, Injectable, token } from "@wyrly/core";Requirements
- TypeScript 5+ with
standard (TC39) decorators
(
experimentalDecorators: false) - ESM (
"type": "module"recommended on Node/Bun) - Deno 2.x, Node.js 20+, Bun, or bundlers that support the above
No reflect-metadata, no emitDecoratorMetadata, no parameter decorators.
Quick start
import { createContainer, Injectable, token } from "@wyrly/core";
const RepoToken = token<{ findById(id: string): Promise<unknown> }>("Repo");
@Injectable({ deps: [RepoToken], lifetime: "scoped" })
class GetUser {
constructor(private readonly repo: { findById(id: string): Promise<unknown> }) {}
}
const container = createContainer();
container.register(RepoToken, {
useValue: { findById: async () => null },
lifetime: "scoped",
});
container.register(GetUser);
const scope = container.createScope();
try {
scope.resolve(GetUser);
} finally {
await scope.dispose();
}Documentation
Related packages
| Package | Deno (JSR) | npm | Description |
| ---------------- | ---------- | --- | --------------------------------- |
| @wyrly/core | yes | yes | Core container, tokens, lifetimes |
| @wyrly/express | yes | yes | Express 5 middleware |
| @wyrly/hono | yes | yes | Hono middleware |
| @wyrly/graphql | yes | yes | GraphQL request scope |
| @wyrly/next | yes | yes | Next.js App Router |
| @wyrly/fresh | yes | — | Fresh 2.x (JSR only) |
License
Apache-2.0 — see LICENSE.
