ShipKit docs
The stack

OpenAPI

Auto-generated OpenAPI 3 spec for the Elysia API, with a Scalar UI reference at /openapi.

The API ships with a typed OpenAPI 3 spec and a Scalar UI reference UI out of the box, via @elysiajs/openapi. The legacy @elysiajs/swagger plugin is not used — it's deprecated as of 2026.

Where to find it

  • Live UI: http://localhost:3001/openapi (or whatever the API host is).
  • Raw JSON: http://localhost:3001/openapi/json.
  • Static export: apps/api/openapi.json is regenerated by apps/api/scripts/export-openapi.ts on every build, and committed to git so consumers (frontend codegen, external SDKs) can read it without running the API.

How it's wired

apps/api/src/app.ts mounts the plugin with mapJsonSchema: { zod: z.toJSONSchema } so any Elysia route declared with t.Object(...) validators or Zod schemas shows up automatically. Every controller's detail: { tags, summary } entries become the section headings and method labels in the UI.

Don't hand-edit the spec — write tighter Elysia route definitions instead, and the UI follows.

Adding routes to the spec

Just declare your validators on the route. The plugin reads them.

app.get(
  "/widgets",
  ({ query }) => listWidgets(query),
  {
    query: t.Object({ limit: t.Optional(t.Number()) }),
    detail: { tags: ["Widgets"], summary: "List widgets" },
  },
);

Hiding a route

Pass detail: { hide: true } on the route, or add it to the plugin's exclude list in app.ts if it's a whole module.

On this page