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 🙏

© 2026 – Pkg Stats / Ryan Hefner

hono-takibi

v0.9.996

Published

Hono Takibi is a code generator from OpenAPI to @hono/zod-openapi

Downloads

1,639

Readme

img

Hono Takibi

img

npm install -D hono-takibi

OpenAPI to Hono Code Generator

Hono Takibi generates type-safe Hono code from OpenAPI / TypeSpec specifications.

  • OpenAPI schemas to Zod schemas
  • @hono/zod-openapi route definitions
  • App entry point + handler stubs + test files
  • Client library hooks (TanStack Query, SWR, Svelte Query, Vue Query)
  • RPC client, mock server, TypeScript types
  • API reference docs with hono-cli commands

Quick Start

CLI

npx hono-takibi path/to/input.{yaml,json,tsp} -o path/to/output.ts

Configuration File

Create hono-takibi.config.ts:

import { defineConfig } from 'hono-takibi/config'

export default defineConfig({
  input: 'openapi.yaml',
  'zod-openapi': {
    output: './src/routes.ts',
  },
})
npx hono-takibi

Example

input:

openapi: 3.1.0
info:
  title: Hono Takibi API
  version: '1.0.0'
paths:
  /:
    get:
      summary: Welcome
      description: Returns a welcome message from Hono Takibi.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: Hono Takibi🔥
                required:
                  - message

output:

import { createRoute, z } from '@hono/zod-openapi'

export const getRoute = createRoute({
  method: 'get',
  path: '/',
  summary: 'Welcome',
  description: 'Returns a welcome message from Hono Takibi.',
  responses: {
    200: {
      description: 'OK',
      content: {
        'application/json': {
          schema: z
            .object({
              message: z.string().openapi({ example: 'Hono Takibi🔥' }),
            })
            .openapi({ required: ['message'] }),
        },
      },
    },
  },
})

Custom Validation Error Messages

Use x-* vendor extensions to customize Zod error messages:

name:
  type: string
  minLength: 1
  x-error-message: 'Name is required'
  x-minimum-message: 'Name cannot be empty'
// Generated output
z.string({ error: 'Name is required' }).min(1, { error: 'Name cannot be empty' })

| Extension | Applies to | | ----------------------------- | ----------------------------------------------------------------- | | x-error-message | Schema constructor (z.string(), z.number(), z.enum(), etc.) | | x-minimum-message | .min(), .gte() | | x-maximum-message | .max(), .lte() | | x-size-message | .length() | | x-pattern-message | .regex() | | x-multipleOf-message | .multipleOf() | | x-enum-error-messages | Per-value enum messages ({ "value": "message" }) | | x-anyOf-message | anyOf | | x-oneOf-message | oneOf | | x-not-message | not | | x-propertyNames-message | propertyNames | | x-dependentRequired-message | dependentRequired |

Branded Types

Use the x-brand vendor extension to generate Zod branded types, creating nominal types that are structurally identical but semantically distinct:

components:
  schemas:
    Cat:
      type: object
      properties:
        name:
          type: string
      required:
        - name
      x-brand: Cat
    Dog:
      type: object
      properties:
        name:
          type: string
      required:
        - name
      x-brand: Dog
// Generated output
const CatSchema = z.object({ name: z.string() }).brand<'Cat'>().openapi('Cat')

const DogSchema = z.object({ name: z.string() }).brand<'Dog'>().openapi('Dog')

Vite Plugin

Watches your OpenAPI spec and hono-takibi.config.ts for changes, then auto-regenerates code on save.

Requires hono-takibi.config.ts in your project root.

// vite.config.ts
import { honoTakibiVite } from 'hono-takibi/vite-plugin'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [honoTakibiVite()],
})

Template & Test Generation

Generate a complete app structure with handler stubs and test files:

export default defineConfig({
  input: 'openapi.yaml',
  'zod-openapi': {
    output: './src/routes.ts',
    template: {
      test: true,
      pathAlias: '@/',
      testFramework: 'bun', // "vitest" (default) | "vite-plus" | "bun"
    },
  },
})

This generates:

  • src/index.ts - App entry point with route registrations
  • src/handlers/*.ts - Handler stubs for each resource
  • src/handlers/*.test.ts - Test files with @faker-js/faker mock data (imports from vitest, vite-plus/test, or bun:test)

Re-running after updating your OpenAPI spec is safe — your hand-written handler logic and test customizations are preserved. Only new routes are added as stubs.

Note: If you remove a path from your OpenAPI spec and re-run, the corresponding handler and test files will be deleted. Make sure to back up or migrate any custom logic before removing API definitions.

Handler Generation Modes

routeHandler: false (default)

Each handler creates its own sub-router and registers routes:

// src/handlers/health.ts
import { OpenAPIHono } from '@hono/zod-openapi'
import { getHealthRoute } from '@/routes'

const app = new OpenAPIHono()

export const healthHandler = app.openapi(getHealthRoute, (c) => {})

The app mounts handlers via .route():

// src/index.ts
import { OpenAPIHono } from '@hono/zod-openapi'
import { healthHandler } from './handlers'

const app = new OpenAPIHono()

export const api = app.route('/', healthHandler)

export default app

routeHandler: true

Handlers export typed RouteHandler functions, and index.ts centralizes route registration:

// src/handlers/health.ts
import type { RouteHandler } from '@hono/zod-openapi'
import type { getHealthRoute } from '../routes'

export const getHealthRouteHandler: RouteHandler<typeof getHealthRoute> = async (c) => {}
// src/index.ts
import { OpenAPIHono } from '@hono/zod-openapi'
import { getHealthRoute } from './routes'
import { getHealthRouteHandler } from './handlers'

const app = new OpenAPIHono()

export const api = app.openapi(getHealthRoute, getHealthRouteHandler)

export default app

Client Library Integrations

Supported: TanStack Query, SWR, Svelte Query, Vue Query, RPC Client.

export default defineConfig({
  input: 'openapi.yaml',
  'zod-openapi': {
    output: './src/routes.ts',
    exportSchemas: true,
  },
  'tanstack-query': {
    output: './src/tanstack-query',
    import: '../client',
    split: true,
    client: 'client',
  },
})

Test & Mock Generation

Test Generation

export default defineConfig({
  input: 'openapi.yaml',
  'zod-openapi': {
    output: './src/routes.ts',
  },
  test: {
    output: './src/test.ts',
    import: '../index',
    testFramework: 'bun', // "vitest" (default) | "vite-plus" | "bun"
  },
})

Mock Server Generation

export default defineConfig({
  input: 'openapi.yaml',
  'zod-openapi': {
    output: './src/routes.ts',
    readonly: true,
  },
  mock: {
    output: './src/mock.ts',
  },
})

API Reference Docs

Generate API reference Markdown with hono-cli hono request commands that can be run directly without starting a server:

export default defineConfig({
  input: 'openapi.yaml',
  'zod-openapi': {
    output: './src/routes.ts',
    readonly: true,
  },
  docs: {
    output: './docs/api.md',
    entry: 'src/index.ts',
  },
})

To generate curl commands instead of hono request:

export default defineConfig({
  input: 'openapi.yaml',
  'zod-openapi': {
    output: './src/routes.ts',
    readonly: true,
  },
  docs: {
    output: './docs/api.md',
    curl: true,
    baseUrl: 'http://localhost:3000',
  },
})

Full Config Reference

split: true - output is a directory (many files + index.ts). split omitted or false - output is a single .ts file. output and routes are mutually exclusive in zod-openapi.

// hono-takibi.config.ts
import { defineConfig } from 'hono-takibi/config'

export default defineConfig({
  // OpenAPI spec file (.yaml, .json, or .tsp)
  input: 'openapi.yaml',

  // Base path prefix for all routes
  basePath: '/api',

  // oxfmt FormatOptions for generated code output
  // @see https://www.npmjs.com/package/oxfmt
  // format: {},

  // Main code generation (Zod + OpenAPI + Hono)
  'zod-openapi': {
    // Output: use 'output' for single file, or 'routes' for split mode (mutually exclusive)
    output: './src/routes.ts',
    readonly: true, // Add 'as const' to generated schemas

    // Template generation (app entry point + handler stubs + tests)
    template: {
      test: true, // Generate test files
      routeHandler: false, // false: inline .openapi() (default), true: RouteHandler exports
      pathAlias: '@/', // TypeScript path alias for imports
      testFramework: 'vitest', // "vitest" (default) | "vite-plus" | "bun" — test import source
    },

    // Export options (OpenAPI Components Object)
    exportSchemas: true,
    exportSchemasTypes: true,
    exportResponses: true,
    exportParameters: true,
    exportParametersTypes: true,
    exportExamples: true,
    exportRequestBodies: true,
    exportHeaders: true,
    exportHeadersTypes: true,
    exportSecuritySchemes: true,
    exportLinks: true,
    exportCallbacks: true,
    exportPathItems: true,
    exportMediaTypes: true,
    exportMediaTypesTypes: true,

    // Split routes into separate files
    routes: {
      output: './src/routes',
      split: true,
      import: '@packages/routes', // Custom import path (monorepo support)
    },

    // Split components into separate files
    components: {
      schemas: {
        output: './src/schemas',
        exportTypes: true,
        split: true,
        import: '../schemas',
      },
      responses: {
        output: './src/responses',
        split: true,
        import: '../responses',
      },
      parameters: {
        output: './src/parameters',
        exportTypes: true,
        split: true,
        import: '../parameters',
      },
      examples: {
        output: './src/examples',
        split: true,
        import: '../examples',
      },
      requestBodies: {
        output: './src/requestBodies',
        split: true,
        import: '../requestBodies',
      },
      headers: {
        output: './src/headers',
        exportTypes: true,
        split: true,
        import: '../headers',
      },
      securitySchemes: {
        output: './src/securitySchemes',
        split: true,
        import: '../securitySchemes',
      },
      links: {
        output: './src/links',
        split: true,
        import: '../links',
      },
      callbacks: {
        output: './src/callbacks',
        split: true,
        import: '../callbacks',
      },
      pathItems: {
        output: './src/pathItems',
        split: true,
        import: '../pathItems',
      },
      mediaTypes: {
        output: './src/mediaTypes',
        exportTypes: true,
        split: true,
        import: '../mediaTypes',
      },
      webhooks: {
        output: './src/webhooks',
        split: true,
        import: '../webhooks',
      },
    },
  },

  // TypeScript type generation
  type: {
    output: './src/types.ts',
    readonly: true,
  },

  // RPC client generation
  rpc: {
    output: './src/rpc',
    import: '../client', // Import path for the Hono RPC client
    split: true,
    client: 'client', // Export name of the client instance
    parseResponse: true, // Use parseResponse for type-safe responses
  },

  // Client library integrations (TanStack Query, SWR, Svelte Query, Vue Query)
  'tanstack-query': {
    output: './src/tanstack-query',
    import: '../client',
    split: true,
    client: 'client',
  },
  'svelte-query': {
    output: './src/svelte-query',
    import: '../client',
    split: true,
    client: 'client',
  },
  swr: {
    output: './src/swr',
    import: '../client',
    split: true,
    client: 'client',
  },
  'vue-query': {
    output: './src/vue-query',
    import: '../client',
    split: true,
    client: 'client',
  },

  // Test generation
  test: {
    output: './src/test.ts',
    import: '../index', // Import path for the app instance
    testFramework: 'vitest', // "vitest" (default) | "vite-plus" | "bun" — test import source
  },

  // Mock server generation
  mock: {
    output: './src/mock.ts',
  },

  // API reference docs generation
  docs: {
    output: './docs/api.md',
    entry: 'src/index.ts', // App entry point for hono request commands
    curl: false, // true: generate curl commands (requires baseUrl), false: hono request (default)
    baseUrl: 'http://localhost:3000', // Base URL for curl commands (required when curl: true)
  },
})

Projects Using Hono Takibi

Limitations

This package is in active development and may introduce breaking changes without prior notice.

  • Not all OpenAPI features are supported
  • Circular references through allOf may cause stack overflow in type generation
  • Some OpenAPI validations may not be perfectly converted to Zod

We strongly recommend:

  • Pinning to exact versions in production
  • Testing thoroughly when updating versions
  • Reviewing generated code after updates

Contributing

We welcome feedback and contributions to improve the tool!

If you find any issues with the generated code or have suggestions for improvements, please:

  • Open an issue at GitHub Issues
  • Submit a pull request with your improvements

License

Distributed under the MIT License. See LICENSE for more information.