Skip to content
petarzarkov edited this page Sep 13, 2026 · 1 revision

FAQ

Questions that come up before anyone opens the guide. Anything about an error message you are looking at belongs in Troubleshooting.

Is this a NestJS fork?

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.

Does it run on Node?

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.

Why is there no @Injectable() or @Inject()?

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.

Do I have to install @dunx/transform?

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.

Why does every relative import end in .js?

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.

Are request-scoped or transient providers supported?

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.

Can I use dunx without HTTP?

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.

Which validation library does it use?

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.

How fast is it, really?

@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.

What does @dunx/core pull in?

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.

Is it production ready?

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.

When should I not use it?

  • 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.

How do I ship it?

Deployment covers Docker and process management. examples/binary compiles an app to a single standalone executable with bun build --compile.

How do I upgrade between versions?

Upgrading tracks the breaking changes, and CHANGELOG.md has every release. The @dunx/* packages version together, so keep them on one version.

Can an AI agent set this up for me?

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.

Where do I report a bug or ask something not covered here?

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.