Server Plugin

The server plugin is the default server-side path for new projects. It is dependency-free and built around the Fetch API.

It generates resource routers such as TodoRouter and the application container TypeweaverApp.

Install note

For the dependency-free server path, add the plugin package:

npm install -D @rexeus/typeweaver-server

Generate server output

npx typeweaver generate --input ./api/spec/index.ts --output ./api/generated --plugins clients,server

Implement handlers and mount the router

Assuming your todo resource currently contains a single GetTodo operation:

import {
  TodoRouter,
  TypeweaverApp,
  createGetTodoSuccessResponse,
  createTodoNotFoundErrorResponse,
} from "./api/generated";

const todoRouter = new TodoRouter({
  requestHandlers: {
    async handleGetTodoRequest(request) {
      if (request.param.todoId !== "todo_123") {
        return createTodoNotFoundErrorResponse({
          body: {
            message: "Todo not found",
            todoId: request.param.todoId,
          },
        });
      }

      return createGetTodoSuccessResponse({
        body: {
          id: "todo_123",
          title: "Ship docs",
          completed: false,
        },
      });
    },
  },
});

const app = new TypeweaverApp();

app.route("/api", todoRouter);

Works well in Fetch API runtimes

TypeweaverApp exposes app.fetch, so it fits naturally into runtimes that already speak Fetch.

Deno.serve({ port: 3000 }, app.fetch);

// or
Bun.serve({ port: 3000, fetch: app.fetch });

This is the main reason the server plugin is a strong default for new projects.

Node.js adapter example

If you want to mount the generated app in Node.js, use the Node adapter path shown in the upstream server package examples:

import { createServer } from "node:http";
import { nodeAdapter } from "./api/generated/lib/server";
import { app } from "./server";

createServer(nodeAdapter(app)).listen(3000);

maxBodySize

TypeweaverApp accepts a maxBodySize option for request parsing. The default is 1_048_576 bytes (1 MB), and requests above that limit return 413.

const app = new TypeweaverApp({
  maxBodySize: 5 * 1024 * 1024,
});

For JSON object bodies, the generated server path sets Content-Type: application/json automatically. Adding that header yourself is optional unless you need to override the default behavior.

What the plugin does for you

The generated server path:

  • matches incoming requests to generated routes
  • validates requests before your handlers run
  • validates handler responses before they are returned
  • keeps the whole boundary aligned with the same contract as the client

Middleware also exists on this path, but deeper middleware patterns belong on Middleware.

When to choose it

Choose the server plugin when:

  • you want a dependency-free setup
  • you want Fetch API-native primitives
  • you are not already committed to Hono

If your app already lives inside Hono, Hono Plugin is usually the smoother fit.

Was this page helpful?