CLIKontractGenerators
← Generators

Client state · OpenAPI

TanStack Query bindings for each operation.

Adds caching and revalidation on top of the generated operations. Pair it with a client target rather than using it alone.

What it emits

Query and mutation hooksQuery options factoriesQuery key helpers

Options

Options this generator adds on top of its base set. Set them under generator: in the target.

OptionDescriptionValuesDefault
envelopeWrap successful responses in a fixed shape. Set `dataKey`, and optionally `metaKey`, `staticFields`, and `contextFields` for path and timestamp.objectunset (no envelope)
hooksEmit the `useX` hooks themselves.true | falsefalse
optionsEmit the standalone query and mutation options factories.true | falsefalse
suspenseAlso emit `useSuspenseX` variants.true | falsefalse
operationsPer-operation overrides keyed by operation id. Each accepts `hooks`, `options`, `suspense`, and `infinite` — where `infinite` needs an explicit `parameter` and `initialPageParam`, because Kontract never guesses pagination policy.objectunset

Shared options

Every OpenAPI generator accepts these, so a schema choice made once stays consistent between a server and its clients.

OptionDescriptionValuesDefault
audiencesApply operation `x-kontract-audiences` policy. `exclude` is validated once against the complete selected OpenAPI source/target universe, not per generated service: siblings with no matching audience generate normally, while a token absent from the whole source fails validation and `generate --clean` preflight before deletion. NestJS may instead set `marker: true` to retain and annotate output.object (exclude: string[]; marker: true for typescript-nestjs)unset (operations belong to every audience)
zodEmit framework-neutral Zod schemas alongside the inferred request and response types.true | falsefalse
schemaModeHow faithfully the source schema is reproduced. `normalize` reshapes inline schemas into named components; `strict` keeps the document as authored.normalize | strictstrict for typescript-nestjs, normalize for SDK targets
useSingleRequestParameterCollapse an operation's parameters into one request object instead of a positional argument list.true | falsefalse
stringEnumsEmit enums as string union types rather than TypeScript `enum` declarations.true | falsefalse
enumUnknownDefaultCaseAdd a fallback member so an unrecognised wire value does not throw at the boundary.true | falsefalse
modelPropertyNamingCasing applied to model properties.camelCase | PascalCase | snake_case | originaloriginal
paramNamingCasing applied to operation parameters.camelCase | PascalCase | snake_case | originaloriginal
enumPropertyNamingCasing applied to enum members.PascalCase | camelCase | snake_case | UPPERCASE | originaloriginal
sortModelPropertiesByRequiredFlagOrder model properties with required ones first.true | falsefalse
sortParamsByRequiredFlagOrder operation parameters with required ones first.true | falsefalse

Example

type: react-query-hooksgenerates

Each operation produces a query-options factory, a skippable variant, and the hook. Enabling suspense adds the suspense hook; mutations get an options factory and hook of their own.

sumr.yamlyaml
targets:
  - name: web-query
    output: ./apps/web/src/api/query
    generator:
      type: react-query-hooks
      zod: true
      suspense: true
Emitted exportsts
// One operation, getProducts, produces:
export function getProductsQueryOptions(/* … */);
export function getProductsSkippableQueryOptions(/* … */);
export function useGetProducts(/* … */);
export function useSuspenseGetProducts(/* … */);

// And for a mutation, createProduct:
export function createProductMutationOptions(/* … */);
export function useCreateProduct(/* … */);

On this page