npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@rcmade/hono-docs

v1.0.31

Published

Auto-generate OpenAPI 3.0 spec from Hono route types

Readme

@rcmade/hono-docs

Auto-generate OpenAPI 3.0 spec and TypeScript type snapshots from Hono route type definitions


Features

  • CLI (@rcmade/hono-docs generate) to:
    • Extract your route AppType definitions via ts-morph
    • Emit .json OpenAPI” files per API prefix under output/*.json
    • Generate a merged openapi.json spec at your configured output path
  • Full TypeScript support (TS & JS config files, inference via defineConfig)

Table of Contents


Install

# using npm
npm install --save-dev @rcmade/hono-docs

# using pnpm
pnpm add -D @rcmade/hono-docs

# using yarn
yarn add -D @rcmade/hono-docs

Quick Start

  1. Create a config file at the root of your project (hono-docs.ts):

    import { defineConfig } from "@rcmade/hono-docs";
    
    export default defineConfig({
      tsConfigPath: "./tsconfig.json",
      openApi: {
        openapi: "3.0.0",
        info: { title: "My API", version: "1.0.0" },
        servers: [{ url: "http://localhost:3000/api" }],
      },
      outputs: {
        openApiJson: "./openapi/openapi.json",
      },
      apis: [
        {
          name: "Auth Routes",
          apiPrefix: "/auth", // This will be prepended to all `api` values below
          appTypePath: "src/routes/authRoutes.ts", // Path to your AppType export
    
          api: [
            // ✅ Custom OpenAPI metadata for the GET /auth/u/{id} endpoint
            {
              api: "/u/{id}", // Final route = /auth/u/{id}
              method: "get",
              summary: "Fetch user by ID", // Optional: title shown in docs
              description: "Returns a user object based on the provided ID.",
              tag: ["User"],
            },
    
            // ✅ Another example with metadata for GET /auth
            {
              api: "/", // Final route = /auth/
              method: "get",
              summary: "Get current user",
              description:
                "Returns the currently authenticated user's information.",
              tag: ["User Info"],
            },
          ],
        },
      ],
    });
  2. Route Definitions & AppType This library supports only change routes via a single AppType export in your routes file. You must export:

    export type AppType = typeof yourRoutesVariable;

    Example:

    // src/routes/userRoutes.ts
    import { Hono } from "hono";
    import { z } from "zod";
    
    export const userRoutes = new Hono()
      .get("/u/:id", (c) => {
        /* … */
      })
      .post("/", async (c) => {
        /* … */
      });
    // Must add AppType
    export type AppType = typeof userRoutes;
    export default userRoutes;

    ⚠️ Limitations: Grouped AppType Not Supported

    Currently, @rcmade/hono-docs does not support extracting route types from a grouped AppType where multiple sub-apps are composed using .route() or .basePath() on a single root app.

    For example, the following pattern is not supported:

    import { Hono } from "hono";
    import { docs } from "./docs";
    import { userRoutes } from "./userRoutes";
    
    const app = new Hono()
      .basePath("/api")
      .get("/", (c) => {
        return c.text("Hello Hono!");
      })
      .route("/docs", docs)
      .route("/user", userRoutes);
    
    // ❌ This Group AppType is not supported
    type AppType = typeof app;

    ✅ Supported: Individual AppType per Module

    Instead, define and export AppType individually for each route module:

    // docs.ts
    import { Hono } from "hono";
    import { Scalar } from "hono-scalar";
    import fs from "node:fs/promises";
    import path from "node:path";
    
    const docs = new Hono()
      .get(
        "/",
        Scalar({
          url: "/api/docs/open-api",
          theme: "kepler",
          layout: "modern",
          defaultHttpClient: { targetKey: "js", clientKey: "axios" },
        })
      )
      .get("/open-api", async (c) => {
        const raw = await fs.readFile(
          path.join(process.cwd(), "./openapi/openapi.json"),
          "utf-8"
        );
        return c.json(JSON.parse(raw));
      });
    
    // ✅ This AppType is supported
    export type AppType = typeof docs;
    // userRoutes.ts
    import { Hono } from "hono";
    
    export const userRoutes = new Hono()
      .get("/", (c) => c.json({ name: "current user" }))
      .get("/u/:id", (c) => c.json({ id: c.req.param("id") }));
    
    // ✅ This AppType is supported
    export type AppType = typeof userRoutes;
  3. Add an npm script to package.json:

    {
      "scripts": {
        "docs": "npx @rcmade/hono-docs generate --config ./hono-docs.ts"
      }
    }
  4. Run the CLI:

    npm run docs
    # or
    npx @rcmade/hono-docs generate --config ./hono-docs.ts

    You’ll see:

    ⏳ Generating Type Snapshots…
    ✅ Wrote: node_modules/@rcmade/hono-docs/output/types/user.d.ts
    ⏳ Generating OpenAPI Spec…
    ✅ OpenAPI written to ./openapi/openapi.json
    🎉 Done

Serving the OpenAPI Docs

Install the viewer:

# npm
npm install @scalar/hono-api-reference

# yarn
yarn add @scalar/hono-api-reference

# pnpm
pnpm add @scalar/hono-api-reference

Mount in your Hono app:

// src/routes/docs.ts
import { Hono } from "hono";
import { Scalar } from "@scalar/hono-api-reference";
import fs from "node:fs/promises";
import path from "node:path";

const docs = new Hono()
  .get(
    "/",
    Scalar({
      url: "/api/docs/open-api",
      theme: "kepler",
      layout: "modern",
      defaultHttpClient: { targetKey: "js", clientKey: "axios" },
    })
  )
  .get("/open-api", async (c) => {
    const raw = await fs.readFile(
      path.join(process.cwd(), "./openapi/openapi.json"),
      "utf-8"
    );
    return c.json(JSON.parse(raw));
  });

export type AppType = typeof docs;
export default docs;

In src/index.ts:

import { Hono } from "hono";
import docs from "./routes/docs";
import userRoutes from "./routes/userRoutes";

export default new Hono()
  .basePath("/api")
  .route("/docs", docs)
  .route("/user", userRoutes);

Visiting /api/docs shows the UI; /api/docs/open-api serves the JSON.


Configuration

All options live in your defineConfig({ ... }) object:

| Field | Type | Required | Description | | ---------------------- | ------------------------------------------------- | -------- | ---------------------------------------------------------------------------- | | tsConfigPath | string | Yes | Path to your project’s tsconfig.json | | openApi | OpenAPIConfig | Yes | Static OpenAPI fields excluding paths, components, and tags | | └ openapi | string | Yes | OpenAPI version (e.g., "3.0.0") | | └ info | { title: string; version: string } | Yes | API title and version metadata | | └ servers | Array<{ url: string }> | Yes | Array of server objects describing base URLs for the API | | outputs | { openApiJson: string } | Yes | File output paths | | └ openApiJson | string | Yes | Path to output the generated openapi.json file | | apis | ApiGroup[] | Yes | Array of route groups to include in the documentation | | └ name | string | Yes | Human-readable name for the route group | | └ apiPrefix | string | Yes | URL path prefix for all routes in this group (e.g., /auth) | | └ appTypePath | string | Yes | File path to the module exporting AppType = typeof routesInstance | | └ api | Array<Api> | No | Optional list of endpoint definitions; if omitted, all in AppType are used | |     └ api | string | Yes | Endpoint path (without prefix), e.g., /user/{id} | |     └ method | "get" \| "post" \| "put" \| "patch" \| "delete" | Yes | HTTP method for the endpoint | |     └ summary | string | No | Short summary for OpenAPI documentation | |     └ description | string | No | Longer description for the endpoint | |     └ tag | string[] | No | Tags used to categorize the endpoint | | preDefineTypeContent | string | No | Optional content injected at the top of each generated .d.ts snapshot |


CLI Usage

Usage: @rcmade/hono-docs generate --config <path> [--output <file>]

Options:
  -c, --config   Path to your config file (TS or JS)        [string] [required]
  -h, --help     Show help                                 [boolean]

Programmatic Usage

You can use the API directly in code:

import { runGenerate, defineConfig } from "@rcmade/hono-docs";

(async () => {
  const cfgPath = 'yourHonoDocs.ts'
  await runGenerate(cfgPath);
})();

Examples

Check out examples/basic-app/ for a minimal setup.


Development

  1. Clone & install dependencies:

    git clone https://github.com/rcmade/hono-docs.git
    cd hono-docs
    pnpm install

    1. Implement or modify code under `src/`.
    2. Build and watch: pnpm build --watch
  2. Test locally via npm link or file: install in a demo project.


Contributing

  1. Fork the repo
  2. Create a feature branch
  3. Open a PR with a clear description & tests
  4. Ensure tests pass & linting is clean

License

MIT