FAQ
Why no decorators or DI container?
Section titled “Why no decorators or DI container?”They add a hidden layer — metadata, registration, resolution order — that
the compiler cannot check and a reader cannot follow. Here a controller gets
its dependencies as function arguments, and the wiring is ordinary code in
one file. Decorators also cannot carry the inferred type of ctx into a
method, so every handler would need a hand-written annotation.
Can a controller be a class?
Section titled “Can a controller be a class?”It can: the framework reads routes from any object and names it after its
class. But class fields are initialized before the constructor assigns its
parameters, so a hook built from a constructor argument in a field is built
from undefined (TypeScript reports TS2729). controller() avoids the
problem. Services stay classes — see
Controllers and dependencies.
Where are onStart and onShutdown?
Section titled “Where are onStart and onShutdown?”There are none. A container needs them because it creates your objects in
an order of its own; here you create them in main.ts, so the order is the
order of the lines. Whatever must happen before the first request, such as
connecting to the database or running migrations, goes before Bun.serve().
For stopping, @tetsujs/lifecycle handles
SIGTERM: it drains the server and then runs the close functions you give
it, in order. See Health checks and shutdown.
Why only Bun?
Section titled “Why only Bun?”Tetsu uses Bun directly: its native router, CookieMap, Bun.serve and
Bun.Server. Other runtimes would need a second router and a wrapper around
everything else, and a second router is a second answer to which route a
request matches.
Is there a plugin system?
Section titled “Is there a plugin system?”No. Packages such as CORS or rate limiting are hooks, mounted in their slot like your own, so everything that runs for a route is visible where it is mounted. See Writing a hook package.
Why is ctx.user from a group hook missing from the handler’s type?
Section titled “Why is ctx.user from a group hook missing from the handler’s type?”A controller is typed where it is written, not where it is mounted, so a group’s hooks do not reach the handler’s type. The hook still runs. To use its field in a handler, mount the hook on the route. See Context and its types.
Why is a path parameter a string?
Section titled “Why is a path parameter a string?”A path segment is text. ctx.params.id is a string until a params
schema converts it, for example with z.coerce.number(). The same holds for
query and form fields.
Can I call the application without starting a server?
Section titled “Can I call the application without starting a server?”Not through routing: routing is Bun’s, and only a socket reaches it. Call a
handler directly with testCtx(), or start a real server on a free port
with serve() from @tetsujs/core/testing. See
Testing.
Is there a typed client, like Eden or Hono RPC?
Section titled “Is there a typed client, like Eden or Hono RPC?”The typed boundary is the OpenAPI document. @tetsujs/openapi builds it
from your routes, and any OpenAPI generator turns it into a client, in
TypeScript or another language. See
Typed client from OpenAPI.
Can I use Express or Hono middleware?
Section titled “Can I use Express or Hono middleware?”No. Middleware wraps next(); a hook has a slot and no next(). Most
middleware maps onto one hook in one slot, and the official packages cover
the common cases: CORS, request ids, logs, rate limits, security headers.
Does the framework read environment variables?
Section titled “Does the framework read environment variables?”No, neither the core nor any package. Read your configuration where the server starts and pass it in; in a test, configuration is then a plain argument.
Is it ready for production?
Section titled “Is it ready for production?”Tetsu is at 0.x: usable, but the API may change between minor versions
until 1.0. Every breaking change is listed in the
release notes with how to
move. See Stability and versioning.
How is it different from Nest, Hono or Elysia?
Section titled “How is it different from Nest, Hono or Elysia?”Controllers and explicit wiring like Nest, without decorators or a container; fixed slots instead of Hono’s middleware; controllers instead of Elysia’s method chain. See Comparison.