Skip to content

TanStack Query (React Query) Hooks

Available since version 3.20.0. The TypeScript client generator can emit a TanStack Query v5 hooks module alongside each generated client module: useQuery hooks for GET endpoints and useMutation hooks for everything else.

Overview

json
json
{
  "NpgsqlRest": {
    "ClientCodeGen": {
      "ReactQuery": {
        "Enabled": false,
        "FilePath": null,
        "FileOverwrite": true,
        "QueryKeyPrefix": null,
        "ExposeQueryKeys": true,
        "ImportFrom": "@tanstack/react-query",
        "HeaderLines": ["// autogenerated at {0}", ""]
      }
    }
  }
}

The ReactQuery section is nested inside ClientCodeGen — hooks are generated from the TypeScript client, so the client generator must be enabled too.

Settings

SettingTypeDefaultDescription
EnabledboolfalseEnable hooks generation. Requires FilePathEnabled without FilePath fails at startup.
FilePathstringnullOutput path for the hooks module. In multi-file mode — BySchema or tsclient_module usage — it must contain {0}, mirroring the FilePath rules of the client generator.
FileOverwritebooltrueOverwrite existing files.
QueryKeyPrefixstringnullLiteral first element of every query key — use it to namespace cache entries when an app consumes multiple NpgsqlRest APIs.
ExposeQueryKeysbooltrueExport query-key factories. When false, key expressions are inlined into the hooks and no factories are exported.
ImportFromstring"@tanstack/react-query"Import specifier for TanStack Query — point it at an internal wrapper module when direct imports are not allowed.
HeaderLinesarray["// autogenerated at {0}", ""]Header lines for the generated file. {0} = timestamp.

Generated Output

Set Enabled to true and point FilePath at the hooks output. Example output for a GET endpoint:

typescript
typescript
export const searchTodosKeys = {
    all: ["searchTodos"] as const,
    byRequest: (request: SearchTodosRequest) =>
        ["searchTodos", request] as const,
};

export function useSearchTodos(
    request: SearchTodosRequest,
    options?: Omit<UseQueryOptions<SearchTodosResult>, "queryKey" | "queryFn">,
) {
    return useQuery({
        queryKey: searchTodosKeys.byRequest(request),
        queryFn: () => api.searchTodos(request),
        ...options,
    });
}

Non-GET endpoints get use{Name}Mutation(options?) with an Omit<UseMutationOptions<Result, unknown, Request>, "mutationFn"> passthrough and no key factory.

Details

  • The hooks import the client functions via a relative import computed from the two FilePath values and derive all types from them (Parameters<typeof fn>[0] / Awaited<ReturnType<typeof fn>>) — nothing depends on ExportTypes or CreateSeparateTypeFile.
  • The whole request object is a query-key segment (TanStack v5 hashes keys with stable, key-order-insensitive serialization), so changing the request re-fetches automatically.
  • QueryKeyPrefix becomes the literal first element of every key — use it to namespace cache entries when an app consumes multiple NpgsqlRest APIs.
  • ExposeQueryKeys: false inlines the key expressions into the hooks and exports no factories.
  • No automatic cache invalidation is generated — wire onSuccess through the options passthrough using the exported key factories.
  • The tsclient_hooks=off routine annotation excludes an endpoint from the hooks file only; the client function is still generated. SSE, upload and url-only endpoints never produce hooks.
  • Hooks output is TypeScript-only: with SkipTypes enabled the run logs a warning and skips hooks generation. Enabled without FilePath fails at startup.
  • ImportFrom replaces the @tanstack/react-query import specifier — point it at an internal wrapper module when direct imports are not allowed (the module must re-export useQuery, useMutation, UseQueryOptions and UseMutationOptions with v5 semantics).
  • The generated file assumes the consumer installs @tanstack/react-query v5 (peer dependency); it compiles under tsc --strict.

Example

Example 23 in the examples repository shows the full setup: hooks with key factories and QueryKeyPrefix, a tsclient_hooks=off opt-out, and a consumer component with explicit cache invalidation through the exported key factories.

For the story behind the feature, see the 3.20.0 release post.

Next Steps

Comments