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

openapi-typescript-express-plugin

v1.0.2

Published

Generate Express handler types from OpenAPI schemas, powered by openapi-typescript

Readme

openapi-typescript-express-plugin

Generate fully-typed Express handler types from OpenAPI 3.x schemas. Powered by openapi-typescript v7.

This package runs openapi-typescript to produce the standard type output (paths, components, operations, etc.), then appends three additional Express-specific interfaces that give you end-to-end type safety for Express route handlers.

Generated Express types

Given an OpenAPI spec, the plugin generates:

  • express<AppLocals, RequestLocals> -- Per-operation detail type containing requestBody, responses, response, request, and handler for each operation.
  • pathHandlers<AppLocals, RequestLocals> -- Handler functions keyed by URL path and HTTP method.
  • operationHandlers<AppLocals, RequestLocals> -- Handler functions keyed by operationId.

Both generic parameters default to Record<string, any> and let you thread your app-level and request-level locals through the type system.

Installation

yarn add -D openapi-typescript-express-plugin
# or
npm install -D openapi-typescript-express-plugin

Your project also needs @types/express installed for the generated types to resolve.

CLI usage

npx openapi-typescript-express-plugin ./openapi.yaml -o ./src/generated/api.ts

The output directory is created automatically if it doesn't exist.

Options

| Flag | Description | |------|-------------| | -o, --output <file> | Output file path (default: stdout) | | --immutable | Generate readonly types | | --enum | Generate TypeScript enums instead of unions | | --alphabetize | Sort types alphabetically | | --exclude-deprecated | Exclude deprecated fields |

Programmatic usage

import { openapiTSExpress } from 'openapi-typescript-express-plugin';

// From a file path
const types = await openapiTSExpress('./openapi.yaml');

// From a URL
const types = await openapiTSExpress('https://api.example.com/openapi.json');

// From an inline spec object
const types = await openapiTSExpress({
  openapi: '3.1.0',
  info: { title: 'My API', version: '1.0.0' },
  paths: { /* ... */ },
});

// With openapi-typescript options
const types = await openapiTSExpress('./openapi.yaml', {
  openapi: { enum: true, immutable: true },
});

You can also use generateExpressTypes directly if you only need the Express type output and are running openapi-typescript separately:

import { generateExpressTypes } from 'openapi-typescript-express-plugin';

const expressTypes = generateExpressTypes(openapiSpecObject);

Example output

For a spec with a GET /users/{id} endpoint (operationId: getUser), the generated Express types look like:

import type { Application, Query } from 'express-serve-static-core';
import type { Request, Response } from 'express';

export type ExpressRequest<
  RequestType extends Request,
  AppLocals extends Record<string, any>, Query
> = Omit<RequestType, "app" | "query"> & { app: Application<AppLocals>, query: Query };

export interface express<AppLocals extends Record<string, any>, RequestLocals extends Record<string, any>> {
  getUser: {
    requestBody: never;
    responses: operations["getUser"]["responses"]["200"]["content"]["application/json"];
    response: Response<express<AppLocals, RequestLocals>['getUser']['responses']>;
    request: ExpressRequest<
      Request<
        operations["getUser"]["parameters"]["path"],
        express<AppLocals, RequestLocals>["getUser"]["responses"] | void,
        express<AppLocals, RequestLocals>["getUser"]["requestBody"],
        Query,
        RequestLocals
      >,
      AppLocals,
      never>;
    handler: (
      req: express<AppLocals, RequestLocals>['getUser']['request'],
      res: express<AppLocals, RequestLocals>['getUser']['response'],
    ) => void | Promise<void>;
  }
}

export interface pathHandlers<AppLocals extends Record<string, any>, RequestLocals extends Record<string, any>> {
  '/users/{id}': {
    get: express<AppLocals, RequestLocals>['getUser']['handler'];
  };
}

export interface operationHandlers<AppLocals extends Record<string, any>, RequestLocals extends Record<string, any>> {
  getUser: express<AppLocals, RequestLocals>['getUser']['handler'];
}

Using the generated types

import type { operationHandlers } from './generated/api.js';

// Type-safe handler with fully typed req.params, req.body, req.query, and res
const getUser: operationHandlers['getUser'] = async (req, res) => {
  const { id } = req.params; // typed as { id: string }
  const user = await db.users.findById(id);
  res.json(user); // type-checked against the response schema
};

How it works

  1. Calls openapi-typescript v7 to generate the standard type output (paths, components, operations)
  2. Parses the OpenAPI spec to walk all paths and operations
  3. Generates Express handler types that reference the operations interface from step 1
  4. Combines both outputs into a single file

This approach keeps the package decoupled from openapi-typescript internals -- it consumes the public API rather than forking the codebase.