vite-plugin-openapi-codegen
v1.0.1
Published
Vite plugin that generates typed API clients and route builders from OpenAPI specs
Downloads
360
Maintainers
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.tsfor raw OpenAPI-derived typesapi.tsfor path builder functionsclient.tsfor 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-plusUsage
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.tsReal 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.tswires the plugin into Viteexample/openapi.jsonis the input specexample/src/http.tsprovides the runtime symbols used by generated clientsexample/src/generated/*is generated during build/dev and is gitignored
Run the example build:
vp build example --config ./example/vite.config.tsRun the example dev server:
vp example --config ./example/vite.config.tsAfter either command, generated files are written to:
example/src/generated/
api-types.d.ts
api.ts
client.tsRuntime Contract
By default, generated clients import the following symbols from #/integrations/http:
requestJsonrequestVoidApiRequestOptions
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 packTo validate the real example project as part of local development:
vp build example --config ./example/vite.config.ts