Skip to main content

@alt-stack/server-hono API Documentation

pnpm add @alt-stack/server-hono hono zod

The adapter supports Hono 4 and Zod 4. It returns a Hono app but does not choose a deployment runtime; use the relevant Hono host adapter, such as @hono/node-server, or export app.fetch where your platform expects it.

createServer(config, options?)

function createServer<TContext extends HonoBaseContext = HonoBaseContext>(
config: Record<string, Router<TContext>>,
options?: CreateServerOptions<TContext>,
): Hono;

Each prefix accepts one router. Call combineRouters() before mounting multiple independent routers at the same prefix.

CreateServerOptions is exported by @alt-stack/server-hono:

PropertyType / defaultRuntime behavior
createContext(c: Context) => Omit<TContext, "hono" | "span"> | Promise<...>Runs after input validation for every matched procedure. Its fields are spread before adapter-owned context.
corsboolean | HonoCorsOptions; default disabledtrue installs Hono's native hono/cors middleware with its defaults. A native options object is passed through unchanged.
docs{ path?: string; openapiPath?: string }Currently unused. It does not create or mount docs. Use createDocsRouter() explicitly.
defaultErrorHandlersresolved handlers from init() or the same shapeCustomizes validation and uncaught-error payloads. Both callbacks are required when the object is supplied; schema properties are optional and ignored by the adapter.
telemetryboolean | TelemetryConfig; default disabledCreates OpenTelemetry server spans except ignored routes.

The adapter:

  1. normalizes each config key as a route prefix and converts {param} to Hono's :param syntax;
  2. reads params and one Hono query object;
  3. attempts c.req.json() for every procedure and substitutes {} when it fails;
  4. validates input asynchronously;
  5. supplies ctx.hono, structured ctx.input, optional custom fields, and ctx.span;
  6. runs procedure middleware and the handler;
  7. passes an Ok<Response> through unchanged, otherwise validates output synchronously and sends JSON.

Only GET, POST, PUT, PATCH, and DELETE procedures are registered. Unknown routes use Hono's normal 404 behavior.

Success and error behavior

  • A handler must return an Altstack Result.
  • Declared Err values are mapped by their error _tag and serialized as { error: { code, message, ...enumerableProperties } }.
  • An unmatched tag becomes status 500.
  • Input validation failures become status 400.
  • Thrown middleware, context, handler, or output-validation errors become status 500.
  • Without custom handlers, the fallback 500 response exposes the thrown stack in error.details.
  • Hono uses synchronous output.parse(), so do not use asynchronous output transforms.

See Error wire formats and OpenAPI for the schema mismatch.

Middleware boundary

createServer() does not accept arbitrary Hono middleware. Define application policies with Altstack procedure middleware so context narrowing, typed errors, and handler composition remain inside the shared server contract:

const protectedProcedure = t.procedure.use(async ({ ctx, next }) => {
const actor = await authenticate(ctx.hono.req);
return actor
? next({ ctx: { actor } })
: err(new UnauthorizedError("Sign in required"));
});

The dedicated cors option is the only adapter-owned native middleware hook. HonoCorsOptions is derived from hono/cors, and the adapter installs it before generated routes without reshaping its behavior.

createDocsRouter(config, options?)

function createDocsRouter<TCustomContext extends object = Record<string, never>>(
config: Record<string, CoreRouter<TCustomContext>>,
options?: CreateDocsRouterOptions,
): CoreRouter<TCustomContext>;

Returns an Altstack core router, not a native Hono router. Mount it in the same createServer() config.

CreateDocsRouterOptions extends GenerateOpenAPISpecOptions:

PropertyDefaultEffect
title"API"OpenAPI title.
version"1.0.0"OpenAPI version string.
descriptionomittedOpenAPI description.
openapiPath"openapi.json"JSON route relative to the docs mount; a leading slash is removed.
enableDocstrueWhen false, omits the root Swagger UI route but keeps the JSON route.

The UI route returns HTML via ctx.hono.html(). It loads Swagger UI 5.10.5 CSS and scripts from unpkg.com. The OpenAPI document is captured when createDocsRouter() runs; later router mutation is not reflected.

const docs = createDocsRouter(
{ "/api": api },
{ title: "Users", version: "1.0.0" },
);
const app = createServer({ "/api": api, "/docs": docs });

Hono-typed routing exports

HonoBaseContext

interface HonoBaseContext extends BaseContext {
hono: Context;
}

Handlers can access the native request, response helpers, environment, and variables through ctx.hono.

Router<TCustomContext>

A subclass of the core Router whose context generic defaults to HonoBaseContext and whose second generic carries tracked route signatures. It adds no runtime members. All inherited public methods are documented in the core Router reference.

router(config)

Calls core router() and casts the result to the Hono-typed subclass. The generic must extend HonoBaseContext. Use it when importing the standalone helper rather than init<AppContext>().router.

createRouter(config?)

Creates an empty Hono-typed router or prefixes one router per config key. Its config accepts routers, not procedures or router arrays. Constructor-style routers are not tracked inputs for checked composition.

combineRouters(...routers)

Combines one or more tracked declarative routers without prefixes. It rejects matching METHOD + canonical path signatures at compile time and repeats the check at runtime; the same path with different methods is valid. See Combining routers for canonicalization, metadata requirements, migration, and troubleshooting.

Core re-exports

The following exports keep their core behavior. Follow the links for signatures, properties, and caveats.

GroupRe-exported names
Initializationinit, publicProcedure, default400ErrorSchema, default500ErrorSchema, InitOptions, InitResult
Result values/typesok, err, isOk, isErr, map, flatMap, mapError, catchError, unwrap, unwrapOr, unwrapOrElse, match, fold, tryCatch, tryCatchAsync, isResultError, assertResultError, ResultAggregateError, TaggedError, Result, Ok, Err, ResultError, InferErrorTag, InferErrorTags, NarrowError
MiddlewarecreateMiddleware, createMiddlewareWithErrors, middlewareMarker, middlewareOk, MiddlewareFunction, MiddlewareBuilder, MiddlewareResult, MiddlewareResultSuccess, MiddlewareFunctionWithErrors, MiddlewareBuilderWithErrors, MiddlewareBuilderWithErrorsStaged, AnyMiddlewareBuilderWithErrors, AnyMiddlewareFunctionWithErrors, Overwrite
Procedures/contextBaseProcedureBuilder, ProcedureBuilder, InputConfig, TypedContext, BaseContext, InferInput, Procedure, ReadyProcedure, PendingProcedure, RouterConfigValue, RouterContext, RouterRouteSignatures, RouteSignature, RouteSignaturesForConfig, ValidateRouterCombination, ValidateRouterConfig
OpenAPIgenerateOpenAPISpec, OpenAPISpec, GenerateOpenAPISpecOptions, OpenAPIPathItem, OpenAPIOperation, OpenAPIParameter, OpenAPIRequestBody, OpenAPIResponse
ValidationvalidateInput, parseSchema, mergeInputs, ParseResult, StructuredInput
TelemetryresolveTelemetryConfig, shouldIgnoreRoute, initTelemetry, createRequestSpan, endSpanWithError, setSpanOk, TelemetryConfig, TelemetryOption, ResolvedTelemetryConfig, Span
Error tagsextractTagsFromSchema, findHttpStatusForError

Hono does not re-export core withActiveSpan or the additional core-only type utilities such as HandlerResult, ValidateErrorConfig, and path-param helper types. Import those from @alt-stack/server-core when required.