Migration: @kubb/plugin-react-query
Part of the v4 → v5 migration guide. For the full option reference, see @kubb/plugin-react-query.
resolver.resolveName replaces transformers.name.
Removed: paramsType, pathParamsType, paramsCasing
These three options are gone, including client.paramsCasing. Each hook now takes its parameters as a single grouped options object shaped as { path, query, body, headers }, with camelCase property names. This matches the shape @kubb/plugin-fetch already used. Query params move under query, path params under path, the request body under body, and header params under headers.
pluginReactQuery({
- paramsType: 'object',
- pathParamsType: 'object',
- paramsCasing: 'camelcase',
})Update the call sites. Query params move into query, and path params move into path. When an operation has a required parameter in a group, that group (path, query, or headers) is required too, so an incomplete call fails to compile.
useFindPets({ status: 'available' })
useGetPet(petId)
useUpdatePet().mutate({ petId, data: pet })useFindPets({ query: { status: 'available' } })
useGetPet({ path: { petId } })
useUpdatePet().mutate({ path: { petId }, body: pet })The first argument is typed Omit<XxxRequestConfig, 'url'>, the RequestConfig type @kubb/plugin-ts generates. The trailing config argument is unchanged.
Generated output
@kubb/plugin-vue-query shares these changes. Both plugins also pick up the renames from the client plugin (*Data, *Response, *Status<code>).
The exported *MutationKey type alias is gone. Use the runtime helper when you need the key:
- export type CreateUserMutationKey = ReturnType<typeof createUserMutationKey>
- export const createUserMutationKey = () => [{ url: '/user' }] as const
+ export const createUserMutationKey = () => [{ url: '/user' }] as constMutation and query TData narrows to 2xx responses
The TData generic on useMutation, useQuery, useInfiniteQuery, useSuspenseQuery, and their *Options helpers now points at the union of 2xx response status types instead of the full response alias. That matches TanStack Query's contract, where TData is the resolved success value and errors flow through TError.
export function useAddPet<TContext>(
options: {
mutation?: MutationObserverOptions<
- AddPetResponse,
+ AddPetStatus200,
ResponseErrorConfig<AddPetStatus405>,
{ data: AddPetData },
TContext
> & { client?: QueryClient }
client?: Partial<RequestConfig<AddPetData>> & { client?: typeof client }
} = {},
) { /* ... */ }Call sites that previously needed as casts or 'id' in res checks compile directly:
const pet = await mutateAsync({ body: { name: 'Rex' } })
pet.id // typed as Pet.id, no narrowing requiredThe change covers queryFn, queryOptions, and the hook generics together. No config flag brings back the old behavior. If your client returns non-2xx bodies as resolved data instead of throwing, wrap it to throw so TanStack Query's error / onError path fires. The previous typing was silently broken at runtime.
No auto enabled guard
v4 generated an enabled guard from the required path and query parameters: enabled: !!path?.petId in React Query, enabled: () => !!toValue(path?.petId) in Vue Query. Those parameters were already required, so !!path.petId was always true. The guard disabled nothing. It read like a safety net and did no work.
v5 removes it. The path, query, and headers groups are required in the generated queryKey, queryOptions, and hook signatures whenever the operation has a required parameter in that group, and nothing emits enabled for you. The query key types only the groups it reads, so a required headers parameter never leaks onto the key.
export function getPetByIdQueryOptions({ path }: Omit<GetPetByIdRequestConfig, 'url'>, config: Partial<RequestConfig> & { client?: Client } = {}) {
const queryKey = getPetByIdQueryKey({ path })
return queryOptions<GetPetByIdStatus200, ResponseErrorConfig<GetPetByIdStatus400 | GetPetByIdStatus404>, GetPetByIdStatus200, typeof queryKey>({
- enabled: !!path?.petId,
queryKey,
queryFn: async ({ signal }) => {
return getPetById({ path }, { ...config, signal: config.signal ?? signal })
},
})
}To defer or disable a query, set TanStack Query's own enabled (or pass skipToken) through the hook options:
// keep the query disabled until petId resolves
useGetPetById({ path: { petId } }, { query: { enabled: !!petId } })NOTE
Suspense hooks always run, so they never had an enabled guard and are unchanged.