Repository navigation
FAQ
Questions that come up before anyone opens the guide. Anything about an error message you are looking at belongs in Troubleshooting.
No. There is no shared code. The programming model is familiar by intent: a container owns object lifetimes, metadata replaces wiring code, and modules draw domain boundaries, the same pattern Spring and Angular established. The mechanism underneath differs in four places, set out in Architecture: dependency injection.
If you are moving an existing app, Migrating from NestJS lists what maps across and what has no equivalent.
No, and there is no plan for it to. There is no CommonJS build and no
compatibility layer. Bun.serve, bun:sqlite, Bun.RedisClient,
Bun.password, Bun.S3Client and Bun.Glob are load-bearing throughout. The
minimum is Bun 1.4.1.
dunx uses TC39 standard decorators, and the proposal has no parameter
decorators, so @Inject() cannot exist. @Injectable() has nothing left to do:
@dunx/transform reads each class's constructor parameter types at load time
with oxc-parser and records them on the
class, so the types themselves are the declaration.
inject() in a field initializer is the escape hatch for the cases constructor
types cannot express, and the two can be mixed in one class.
To use constructor injection, yes, and the scaffolder wires it. It runs as a Bun preload:
preload = ["@dunx/transform/preload"]
[test]
preload = ["@dunx/transform/preload"]Both entries matter. Bun's test runner reads the [test] key separately, so an
app that boots fine can still fail on the first bun test run.
The scaffold sets moduleResolution: nodenext, where an extensionless relative
specifier is a compile error rather than a runtime surprise. Write
./users.service.js even though the file on disk is .ts.
No. There is no Scope.REQUEST, no Scope.TRANSIENT, and no plan to add
either. Both were measured and turned down as a container's largest source of
per-request cost and complexity. The reasoning and the numbers are in
Lifecycle.
Request-scoped context is a separate thing and is supported. Correlation ids
and per-request state ride in RequestContext, which is backed by
AsyncLocalStorage rather than by the container. See
Logging.
Yes. AppFactory.create in @dunx/core gives you the container, modules,
lifecycle hooks, config and events with no server attached. Workers, CLIs and
queue consumers use it. HttpFactory.create in @dunx/http is the same factory
with Bun.serve on top.
Whichever you like, as long as it implements
Standard Schema. zod, Valibot and ArkType all drop
in without an adapter, and the same schema a route validates is the one
@dunx/openapi documents. See Validation.
@dunx/http is a layer over Bun.serve({ routes }) and 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.
Reproduce it with bun run --filter '@dunx/bench' start. The harness 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. Full
methodology in
internal/bench/README.md.
Nothing. Its dependencies block is empty. Every other package depends only on
@dunx/*, @arkv/* or oxc-parser, and the libraries it integrates (zod,
drizzle-orm, better-auth, bullmq) are peers you install yourself. A gate in CI
enforces that.
It is at v3.8.1, every published workspace holds 90% line and function
coverage as a CI gate, and five examples run on every commit.
Firecracker is a real app built on
it: 21 modules, 8 controllers, a WebSocket gateway and 4 job handlers across 165
backend files.
The honest caveat is the ecosystem. There is no large body of third-party dunx packages yet, so anything outside what the framework ships is yours to write.
- You do not want DI. Elysia and Hono own that space and 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.
- You are not certain you are on Bun.
Deployment covers Docker and process
management.
examples/binary
compiles an app to a single standalone executable with bun build --compile.
Upgrading tracks the breaking changes, and
CHANGELOG.md has
every release. The @dunx/* packages version together, so keep them on one
version.
Point an agent at setup.md: "set up my project
using https://dunx.win/setup.md".
llms.txt links every document as raw markdown, and
@dunx/mcp is an MCP server that serves the guide and, once pointed at an app,
that app's own routes, providers and modules. Every scaffolded project also gets
an AGENTS.md and a CLAUDE.md.
Open an issue with the steps that reproduce it. Security reports follow SECURITY.md instead. Pull requests are welcome, and CONTRIBUTING.md is the full guide to the checks CI runs.