Dependency injection for Bun. Everything a service needs, one version.
Controllers, dependency injection, validation, OpenAPI, WebSockets, queues, an
ORM, auth, a test harness and an ops dashboard. Released together, tested
together, on Bun's own primitives.
A Model Context Protocol server for dunx: the written guide and scaffold catalogue with no app, plus your routes, providers and modules once you point it at one
2026-10-28
Yıldızlar
—
Araçlar
—
Çalışma süresi
—
bunx @dunx/create-app my-api
What you get
Elysia and Hono hand you a router, and everything above it is yours to choose
and keep in step. This is the other trade: one dependency, one release train.
One validate function over Bun.env, YAML, TOML or JSON, typed end to end
Validation
Standard Schema, so zod, Valibot or ArkType all drop in
API documentation
OpenAPI 3.1 from the routes' own schemas, behind Swagger UI or Scalar
Realtime
WebSocket gateways and @Sse, with a Redis or Postgres relay for many nodes
Service to service
Connect and gRPC-Web, through the middleware chain the app has
Decoupling
An in-process event bus: publish a class, subscribe with @OnEvent
Data
drizzle over bun:sqlite and Bun.SQL, transactions, seeds, paging
Caching
Memory, Redis or the two tiered, with single flight on a miss
Background work
bullmq over Bun.RedisClient, sandboxed processors, @Cron
Messaging
RabbitMQ topic exchanges, one handler per queue, the trace carried across
Storage and images
One Storage contract over Bun.file and Bun.S3Client, Bun.Image
Auth
better-auth mounted, a session guard, Bun.password hashing
Calling out
An HTTP client with retry, backoff and trace propagation
Failing well
ResiliencePolicy around anything: timeout, retry, backoff, jitter, fallback
Operating it
Health checks, structured logging, request and driver metrics, a dashboard
Testing
The real container with bindings replaced, a real server on port 0
Tooling
A scaffolder, and an MCP server so an agent can read your app
Every one of those is a Bun primitive or a best-in-class library wired to one,
never a reimplementation. Each is opt-in: @dunx/core has zero dependencies,
and an app that imports no queue installs no queue.
What an app looks like
import { Logger, Module } from '@dunx/core';
import {
Controller,
Get,
HttpFactory,
type Input,
type RouteSchemas,
} from '@dunx/http';
export class GreetingsService {
constructor(private readonly logger: Logger) {}
greet(name: string) {
this.logger.info('greeting', { name });
return { greeting: `hello, ${name}` };
}
}
@Controller('greetings')
export class GreetingsController {
constructor(private readonly greetings: GreetingsService) {}
@Get('/:name')
one(input: Input<RouteSchemas>) {
return this.greetings.greet(input.req.params['name'] ?? 'world');
}
}
@Module({
controllers: [GreetingsController],
providers: [GreetingsService],
})
export class AppModule {}
const app = await HttpFactory.create(AppModule);
await app.listen(3000);
There is no @Injectable(), no @Inject(), no reflect-metadata import and no
experimentalDecorators, and a handler returns a plain value instead of calling
Response.json(). Two lines in bunfig.toml turn the constructor types into
wiring:
Bun's test runner reads its own preload, so bun test needs the [test]
entry. Without it the app runs, but the tests fail at the first provider with a
constructor parameter.
How the DI differs
The constructor injection above reads like NestJS. The mechanism resolving it
underneath is different, in four places.
No reflect-metadata, and no experimentalDecorators. dunx uses standard
TC39 decorators. @dunx/transform reads each class's constructor parameter
types at load time with oxc-parser, a
Rust parser over N-API, and records them on the class. There are no parameter
decorators in the TC39 proposal, so @Inject() does not exist and never will.
A type that does not exist at runtime fails boot. If a parameter's type is
an interface, a primitive or a type-only import, dunx fails at boot and names
that parameter. emitDecoratorMetadata gives you undefined and a stack trace
three frames away from the mistake.
No forwardRef. The dependency record is a thunk, evaluated at resolution
rather than at class-definition time, so a circular import resolves on its own.
The container is scoped. Every module reference is a scope holding what it
declares, exports is its public surface, and an absent exports exports
nothing. A module that takes no options is a decorated class rather than a
forRoot(), because each forRoot() call returns a fresh object and so a fresh
scope.
One thing to add rather than delete: every relative import ends in .js,
because moduleResolution: nodenext is what the scaffold sets. An extensionless
specifier is a compile error rather than a runtime surprise.
Documentation
The live demo - examples/full running on a
Raspberry Pi 5: the API explorer, the ops dashboard, bull-board, and a
walkthrough that drives twenty-five capabilities from a browser, including a
transaction rolling back, a CSRF refusal, an idempotent retry, an order
crossing a RabbitMQ topic exchange, and the process's own request, query and
event-loop timings
The guide - thirty-five pages,
introduction through cookies
setup.md - the same setup for
an agent to fetch and follow: "set up my project using
https://dunx.win/setup.md". Every scaffolded app also gets an
AGENTS.md and a CLAUDE.md
llms.txt - every document
above, linked as raw markdown
Performance
Structure on Bun does not have to cost throughput. @dunx/http is a layer over
Bun.serve({ routes }). It lands at 88-99% of the raw server's throughput,
within noise of Elysia, and 3.8-5.5x NestJS on Fastify. Boot is 43 ms against
294 ms.
Median req/s, 64 connections, 5 runs:
Framework
Plain text
JSON
Path param
Body validation
@dunx/http
134,864
127,776
126,206
81,631
Elysia
136,766
123,937
127,885
78,649
Hono (Bun)
126,987
111,301
108,403
60,513
NestJS (Fastify)
31,623
33,748
29,606
14,953
Bun.serve (raw)
136,500
131,077
130,479
92,616
The harness also runs Go, Rust and JVM subjects alongside these. The NestJS
subject is real NestJS with real reflect-metadata. It states what it cannot
measure, too: the load generator shares a machine with the subject, and the
closed-loop design is subject to coordinated omission.
Reproduce it with bun run --filter '@dunx/bench' start. The methodology is in
internal/bench/README.md.
When not to use it
You do not want DI. Elysia and Hono own that space, they are mature, and
they are faster to learn.
Boot time is your critical number. 43 ms is fine for a service that starts
once and stays up, and wrong for a per-invocation serverless function.
You need request-scoped or transient providers. Not supported, rejected
with measurements.
You are not certain you are on Bun. No CommonJS build, no Node
compatibility layer. Bun.serve, bun:sqlite, Bun.RedisClient and
Bun.password are load-bearing throughout.
You want a mature third-party ecosystem. There is not one yet.
Better Auth for dunx: its handler mounted on Bun.serve, a session guard reading @Public() and @Roles(), the caller in async context, and Bun.password hashing
An opt-in operations page for a running dunx app: routes, the provider graph, gateways, config and runtime health, with bull-board mounted for the queues
Database, Redis, queue, AMQP, schedule, storage, image and logging infrastructure for dunx. drizzle over bun:sqlite and Bun.SQL, bullmq over Bun.RedisClient, rabbitmq-client for RabbitMQ, plus Bun.file, Bun.Glob, Bun.S3Client, Bun.Image and @arkv/logger
A Model Context Protocol server for dunx: the written guide and scaffold catalogue with no app, plus your routes, providers and modules once you point it at one
Contributing
Pull requests are welcome. CONTRIBUTING.md is the full guide: how
to get set up, which checks CI runs, the repo's rules on native implementations and
third-party dependencies, and the house style a review will hold you to.
The short version: Bun only, no npm/npx/yarn/pnpm; bun install then
bun run build before anything else; run bun run ci, every gate CI runs, before
you push; conventional commits; a bug fix comes with the test
that would have caught it; and a claim about performance comes with the numbers.
A Model Context Protocol server for dunx: the written guide and scaffold catalogue with no app, plus your routes, providers and modules once you point it at one
Henüz araç listesi yok. Uzak sunucular ilk sağlık kontrolünden sonra bir liste alır.
SSS
Sorular
@dunx/mcp nasıl kurulur?
Bu sayfadan Cursor, Claude Desktop, Claude Code veya VS Code için stdio yapılandırmasını kopyalayın. PlugMCP proxy'sini değil, yayıncının kurulumunu kullanır.
@dunx/mcp için API anahtarı gerekiyor mu?
Bu kayıtta gerekli bir ortam değişkeni listelenmiyor.
@dunx/mcp hangi aktarımı kullanıyor?
@dunx/mcp yerel olarak stdio üzerinden çalışır.
@dunx/mcp en son ne zaman kontrol edildi?
Son kontrol: 2026-10-28. A Model Context Protocol server for dunx: the written guide and scaffold catalogue with no app, plus your routes, providers and modules once you point it at one