Repository navigation
Home
Dependency injection for Bun. Controllers, scoped modules, validation, OpenAPI, WebSockets, queues, an ORM, auth, a test harness and an ops dashboard, released together and tested together on Bun's own primitives.
bunx @dunx/create-app my-apiLatest release v3.8.1. Requires Bun >=1.4.1. MIT licensed.
Guide · Live demo · Coverage · Releases · npm
The reference material lives in the repository and is published at dunx.win. This wiki holds what sits around it: a map of where to look, the questions people ask first, and the errors they hit after.
Pages here link to the guide rather than restate it, so nothing goes stale in two places at once.
| You want to | Read |
|---|---|
| Get an app running | First steps |
| Look up one capability | The guide index below |
| Understand a decision | ARCHITECTURE.md |
| Move an existing NestJS app | Migrating from NestJS |
| Fix an error you are staring at | Troubleshooting |
| Ask the obvious question first | FAQ |
| See it running before committing | demo.dunx.win |
| Send a pull request | CONTRIBUTING.md |
| Point an agent at it | setup.md, llms.txt |
import { Module } from '@dunx/core';
import { Controller, Get, HttpFactory } from '@dunx/http';
export class GreetingsService {
greet(name: string): string {
return `hello, ${name}`;
}
}
@Controller('greetings')
export class GreetingsController {
constructor(private readonly greetings: GreetingsService) {}
@Get('/')
index(): { greeting: string } {
return { greeting: this.greetings.greet('world') };
}
}
@Module({
controllers: [GreetingsController],
providers: [GreetingsService],
})
export class AppModule {}
const app = await HttpFactory.create(AppModule);
await app.listen(3000);There is no @Injectable() and no @Inject(). The constructor parameter types
are the wiring, and two entries in bunfig.toml are what read them:
preload = ["@dunx/transform/preload"]
[test]
preload = ["@dunx/transform/preload"]Bun's test runner reads its own preload key, so the [test] entry is what
keeps bun test working. Miss it and the app boots while the suite fails at the
first provider that takes a constructor parameter. bunx @dunx/create-app
writes both for you.
Twenty-eight pages, published at dunx.win and written in
docs/guide/.
Getting started Introduction · First steps
Fundamentals Providers · Modules · Controllers · Validation · Lifecycle
Techniques Middleware and guards · WebSockets · OpenAPI · Testing
Infrastructure Configuration · Logging · Database · Caching · Queues · Scheduling · Authentication · Files and images
Going live Deployment · Health checks · Agent tooling · Metrics · Upgrading · Resilience
Messaging Events · RPC · Message brokers
Each one is opt-in. @dunx/core has zero dependencies, and an app that imports
no queue installs no queue.
| Package | Holds |
|---|---|
@dunx/core |
Container, modules, lifecycle, config, events, resilience |
@dunx/http |
Bun.serve adapter, controllers, middleware, gateways |
@dunx/transform |
The load-time transform that records constructor types |
@dunx/infra |
Database, Redis, queues, AMQP, schedule, storage, images |
@dunx/openapi |
OpenAPI 3.1 from the routes' own schemas |
@dunx/auth |
better-auth mounted, a session guard, password hashing |
@dunx/testing |
The real container with bindings replaced |
@dunx/dashboard |
An opt-in operations page for a running app |
@dunx/create-app |
The scaffolder |
@dunx/mcp |
An MCP server so an agent can read your app |
Each runs in CI, and each exits 0 with no database, Redis or S3 installed.
| Example | Answers |
|---|---|
minimal |
What does it look like? Five files |
databases |
SQLite async and sync, Postgres, MySQL |
testing |
Overrides, a real server on port 0, a guard |
full |
Every package in one long-running service |
binary |
One standalone compiled executable |
- A bug, with the steps that reproduce it: open an issue
- A security report: SECURITY.md
- A question: check FAQ and Troubleshooting first, then open an issue