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

vite-plugin-openapi-codegen

v1.0.1

Published

Vite plugin that generates typed API clients and route builders from OpenAPI specs

Downloads

360

Readme

vite-plugin-openapi-codegen

Generate typed API clients and path builders from an OpenAPI document during Vite builds.

The plugin reads your OpenAPI spec, runs openapi-typescript, and emits three files into your target directory:

  • api-types.d.ts for raw OpenAPI-derived types
  • api.ts for path builder functions
  • client.ts for typed request helpers

It also watches the input spec in dev mode and regenerates the files when the spec changes.

Installation

This package is built for vite-plus.

vp add -D vite-plugin-openapi-codegen vite-plus

Usage

Add the plugin to your Vite config:

import { defineConfig } from "vite-plus";
import { openapiCodegen } from "vite-plugin-openapi-codegen";

export default defineConfig({
  plugins: [
    openapiCodegen({
      input: "openapi.json",
      output: "src/generated",
    }),
  ],
});

When you run vp dev or vp build, the plugin generates:

src/generated/
  api-types.d.ts
  api.ts
  client.ts

Real Example Project

This repository includes a real minimal Vite project under example/ that demonstrates automatic generation from vite.config.ts.

Key files:

  • example/vite.config.ts wires the plugin into Vite
  • example/openapi.json is the input spec
  • example/src/http.ts provides the runtime symbols used by generated clients
  • example/src/generated/* is generated during build/dev and is gitignored

Run the example build:

vp build example --config ./example/vite.config.ts

Run the example dev server:

vp example --config ./example/vite.config.ts

After either command, generated files are written to:

example/src/generated/
  api-types.d.ts
  api.ts
  client.ts

Runtime Contract

By default, generated clients import the following symbols from #/integrations/http:

  • requestJson
  • requestVoid
  • ApiRequestOptions

The default runtime shape is designed for an app-level HTTP wrapper like this:

export interface ApiRequestOptions {
  headers?: Record<string, string>;
  json?: unknown;
  method: string;
  searchParams?: URLSearchParams;
  signal?: AbortSignal;
}

export async function requestJson<T>(path: string, options: ApiRequestOptions): Promise<T> {
  // Your app-specific HTTP implementation
  throw new Error("Not implemented");
}

export async function requestVoid(path: string, options: ApiRequestOptions): Promise<void> {
  // Your app-specific HTTP implementation
  throw new Error("Not implemented");
}

If your runtime uses different symbol names or a different module path, configure httpClient:

import { defineConfig } from "vite-plus";
import { openapiCodegen } from "vite-plugin-openapi-codegen";

export default defineConfig({
  plugins: [
    openapiCodegen({
      input: "openapi.json",
      output: "src/generated",
      httpClient: {
        module: "@app/http",
        jsonFunction: "fetchJson",
        voidFunction: "fetchVoid",
        requestOptionsType: "RequestOptions",
        omitKeys: ["json", "method", "signal"],
      },
    }),
  ],
});

Generated Output

Given a spec path like /api/users/{user_id}, the plugin generates a path builder:

import type { components } from "./api-types";

export function getUser(params: components["schemas"]["UserPath"]): string {
  return `users/${params.user_id}`;
}

And a typed client helper:

import type { components } from "./api-types";

export interface GetUserOptions {
  query?: never;
  path: components["schemas"]["UserPath"];
  body?: never;
  signal?: AbortSignal;
}

export function getUser(
  options: GetUserOptions,
  requestOptions: RuntimeRequestOptions = {},
): Promise<components["schemas"]["UserResponse"]> {
  return requestJson<components["schemas"]["UserResponse"]>(buildGetUserPath(options.path), {
    ...requestOptions,
    method: "GET",
    signal: options.signal,
  });
}

The generated client shape depends on the OpenAPI operation:

  • path parameters become options.path
  • query parameters become options.query
  • JSON request bodies become options.body
  • JSON responses become typed Promise<T>
  • empty responses use the configured void request function

Options

interface Options {
  input: string;
  output: string;
  pathPrefix?: string;
  stripPrefix?: boolean;
  httpClient?: {
    module?: string;
    jsonFunction?: string;
    voidFunction?: string;
    requestOptionsType?: string;
    omitKeys?: string[];
  };
}

input

Path to the OpenAPI JSON file, relative to the Vite project root.

output

Directory where generated files are written, relative to the Vite project root.

pathPrefix

Only paths starting with this prefix are included. The default is "/api/".

stripPrefix

Controls whether the pathPrefix is removed from generated path builders. The default is true.

httpClient

Overrides the runtime import path and symbol names used by generated clients.

Programmatic Usage

If you want to generate artifacts outside the Vite lifecycle, use renderGeneratedArtifacts:

import { readFileSync } from "node:fs";
import { renderGeneratedArtifacts } from "vite-plugin-openapi-codegen";

const spec = JSON.parse(readFileSync("openapi.json", "utf-8"));

const files = renderGeneratedArtifacts(spec, {
  pathPrefix: "/api/",
  stripPrefix: true,
});

console.log(files.api);
console.log(files.client);

Development

vp install
vp test
vp check
vp pack

To validate the real example project as part of local development:

vp build example --config ./example/vite.config.ts