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

@korix/openapi-plugin

v0.4.0

Published

OpenAPI plugin for Kori framework

Downloads

29

Readme

@korix/openapi-plugin

OpenAPI 3.1 document generation plugin for Kori framework.

Note: This is the base plugin for OpenAPI document generation. For actual use, you'll typically use @korix/std-schema-openapi-plugin which provides Standard JSON Schema support for Zod, Valibot, ArkType, and other schema libraries. This package provides the core OpenAPI generation functionality and schema converter interface.

Features

  • Automatic OpenAPI 3.1.0 document generation from Kori routes
  • Path parameter auto-generation from route patterns
  • Automatic operationId generation (customizable)
  • Request/response schema conversion to OpenAPI format
  • Route metadata support (summary, description, tags)
  • Route exclusion control
  • Document caching for performance

Installation

npm install @korix/openapi-plugin

Basic Usage

import { createKori } from '@korix/kori';
import { openApiPlugin } from '@korix/openapi-plugin';

const app = createKori()
  .applyPlugin(
    openApiPlugin({
      info: {
        title: 'My API',
        version: '1.0.0',
        description: 'API documentation',
      },
      converters: [mySchemaConverter],
    }),
  )
  .get('/users/:id', {
    requestSchema: myRequestSchema,
    handler: (ctx) => {
      const { id } = ctx.req.params();
      return ctx.res.json({ id, name: 'John' });
    },
  });

// OpenAPI document available at: GET /openapi.json

Configuration

Plugin Options

openApiPlugin({
  // Required: API information
  info: {
    title: string;
    version: string;
    description?: string;
    // ... other OpenAPI InfoObject fields
  },

  // Required: Schema converters for your validation library
  converters: SchemaConverter[];

  // Optional: Custom document endpoint path (default: '/openapi.json')
  documentPath?: string;

  // Optional: Server configurations
  servers?: ServerObject[];
})

Route Metadata

Use openApiMeta() to add OpenAPI-specific metadata to routes:

import { openApiMeta } from '@korix/openapi-plugin';

app.get('/users', {
  pluginMeta: openApiMeta({
    summary: 'List users',
    description: 'Get all users in the system',
    tags: ['users'],
    operationId: 'listUsers', // Optional: override auto-generated ID
    exclude: false, // Optional: exclude from OpenAPI document
  }),
  handler: (ctx) => ctx.res.json([]),
});

Path Parameters

Automatic Generation

Path parameters are automatically extracted from route patterns:

app.get('/users/:id', {
  handler: (ctx) => ctx.res.json({ id: ctx.req.param('id') }),
});

Generates:

{
  "paths": {
    "/users/{id}": {
      "get": {
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ]
      }
    }
  }
}

Schema Enrichment

Provide a params schema to add type information and descriptions:

import { stdRequestSchema } from '@korix/std-schema-adapter';
import { z } from 'zod';

app.get('/users/:id', {
  requestSchema: stdRequestSchema({
    params: z.object({
      id: z.uuid().meta({ description: 'User UUID' }),
    }),
  }),
  handler: (ctx) => ctx.res.json({ id: ctx.req.param('id') }),
});

Generates:

{
  "parameters": [
    {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "User UUID",
      "schema": {
        "type": "string",
        "format": "uuid",
        "description": "User UUID"
      }
    }
  ]
}

Operation ID

Operation IDs are automatically generated from method and path:

| Path | Method | Generated operationId | | ------------------------------ | ------ | ------------------------------- | | / | GET | getIndex | | /users | GET | getUsers | | /users/:id | GET | getUsersById | | /teams/:teamId/users/:userId | GET | getTeamsByTeamIdUsersByUserId |

Override with metadata:

app.get('/users', {
  pluginMeta: openApiMeta({ operationId: 'listAllUsers' }),
  handler: (ctx) => ctx.res.json([]),
});

Advanced Path Patterns

The plugin handles advanced Hono-style path patterns:

Optional Parameters

app.get('/api/:version?', {
  handler: (ctx) => ctx.res.json({}),
});
// Converts to: /api/{version}

Regex Constraints

app.get('/post/:date{[0-9]+}', {
  handler: (ctx) => ctx.res.json({}),
});
// Converts to: /post/{date}
// Regex constraint is removed (OpenAPI doesn't support it)

Unsupported Patterns

The following patterns are not supported by OpenAPI and will be skipped with an info-level log:

Wildcard Paths

app.get('/files/*', {
  handler: (ctx) => ctx.res.text('file'),
});
// Skipped: OpenAPI doesn't support wildcard syntax
// Log: "Skipping route with wildcard path"

Custom HTTP Methods

app.route({
  method: { custom: 'CUSTOM' },
  path: '/custom',
  handler: (ctx) => ctx.res.json({}),
});
// Skipped: OpenAPI only supports standard HTTP methods
// Log: "Skipping route with custom HTTP method"

Excluding Routes

Exclude specific routes from the OpenAPI document:

app
  .get('/public', {
    handler: (ctx) => ctx.res.json({}),
  })
  .get('/internal', {
    pluginMeta: openApiMeta({ exclude: true }),
    handler: (ctx) => ctx.res.json({}),
  });
// Only /public appears in OpenAPI document

Document Caching

The OpenAPI document is generated once and cached. It's regenerated only when route definitions change (during development with hot reload).

Implementation Notes

Path Parameter Handling

  • Path pattern is the source of truth for parameter names
  • Schema enriches path parameters with type information and metadata
  • Schema properties not present in the path are ignored with a warning
  • All path parameters are required: true (per OpenAPI specification)

Conversion Failures

When schema conversion fails, the plugin logs a warning and:

  • Request body: Returns undefined (no requestBody in operation)
  • Response: Skips the response
  • Path parameters: Uses default { type: 'string' } for parameters not in schema

Logging

All conversion failures and skipped routes are logged with contextual information:

  • Route context (method, path) via log.child()
  • Provider information for failed conversions
  • Property/parameter names for mismatches

TypeScript

The plugin extends the Kori environment type with OpenAPI configuration:

type OpenApiEnvExtension = {
  openapi: {
    documentPath: string;
  };
};

Access configuration in handlers:

const documentPath = ctx.env.openapi.documentPath;

License

MIT