@kubb/plugin-fetch
@kubb/plugin-fetch turns each OpenAPI operation into a typed async function that calls your API with the global Fetch API. The path, query parameters, request body, response, and error shape all come from the spec, so a call stays in sync with the API it targets.
From your spec, the generated client gives you:
- Typed functions per operation with grouped
path,query,headers, andbody. - A status-keyed result on every call, or a thrown
ResponseError. - Auth resolved from your OpenAPI security schemes.
- Serialization of parameters and bodies across content types, including
multipart/form-datauploads and binary downloads. - Runtime validation against
@kubb/plugin-zodschemas. - Typed server-sent events you read with
for await. - Interceptors and a custom transport for the send.
- Standalone functions or a class-based SDK.
It builds on @kubb/plugin-ts for the types, so add that to your config. The client uses the built-in fetch, so there is no extra HTTP dependency to install.
Each function takes one grouped options object ({ path, query, headers, body }) and returns a RequestResult of { status, data, error, contentType, request, response }, bundled into .kubb/client.ts. See error handling for throwOnError and the status-keyed result union.
The bundled client also exposes getUrl, which builds an operation's final URL without sending the request, useful for cache keys, prefetch, and links:
import { client } from './.kubb/client'
const url = client.getUrl({ url: '/pet/{petId}', path: { petId: 1 }, query: { status: ['available'] } })
// '/pet/1?status=available'The runtime sets method, headers, body, signal, and credentials itself. To reach the rest of RequestInit (cache, mode, redirect, keepalive, duplex, or Next.js's next), pass options, on the client or per call, where a per-call value wins:
import { client } from './.kubb/client'
import { getPetById } from './getPetById'
client.setConfig({ options: { cache: 'no-store' } })
await getPetById({ path: { petId: 1 }, options: { cache: 'force-cache', next: { revalidate: 60 } } })For cross-cutting concerns like retries and interceptors, reach for a custom transport instead.
Installation
bun add -d @kubb/plugin-fetch@betapnpm add -D @kubb/plugin-fetch@betanpm install --save-dev @kubb/plugin-fetch@betayarn add -D @kubb/plugin-fetch@betaDependencies
This plugin needs @kubb/plugin-ts in your config. Kubb runs it before plugin-fetch so the functions can import the generated types. When validator is set to 'zod', also add @kubb/plugin-zod.
Example
import { } from 'kubb'
import { } from '@kubb/plugin-ts'
import { } from '@kubb/plugin-fetch'
export default ({
: { : './petStore.yaml' },
: { : './src/gen' },
: [
(),
({
: { : 'clients', : { : 'named' } },
: 'https://petstore.swagger.io/v2',
: {
: 'tag',
: ({ }) => `${}Service`,
},
}),
],
})