Your API schema is the source of truth
use-q is an opinionated way to use TanStack Query: one schema becomes typed hooks, hierarchical query keys, and automatic invalidation — TkDodo's Practical React Query patterns, without giving up Query itself.
Define once, use everywhere
Describe each route's method, path, params, body, response, and cache tags in a single place. Every hook, query key, and invalidation is derived from it.
const schema = {
listPosts: {
method: "GET",
path: "/facilities/{facilityId}/posts",
tags: ["posts"],
} satisfies RouteDefinition<
{ facilityId: string }, // path params
{ search?: string }, // search params
never, // body
Post[] // response
>,
createPost: {
method: "POST",
path: "/facilities/{facilityId}/posts",
invalidatesTags: ["posts"],
} satisfies RouteDefinition<{ facilityId: string }, never, { title: string }, Post>,
} as const;
export const api = createApiClient(schema, {
baseUrl: "https://api.example.com",
});function PostList({ facilityId }: { facilityId: string }) {
// data is Post[] — inferred, not asserted
const { data } = api.useQ("listPosts", { params: { facilityId } });
const createPost = api.useM("createPost");
// listPosts refetches automatically after this succeeds
return (
<button
onClick={() =>
createPost.mutate({ params: { facilityId }, body: { title: "Hi" } })
}
/>
);
}Why use-q?
TkDodo's Practical React Query series, as a thin schema-driven layer over TanStack Query — query keys, invalidation, and types you would otherwise wire by hand. See the map.
End-to-end type safety
Path params, search params, bodies, responses, and error payloads are all inferred from a single schema. No `any` leaks into your components.
Framework-agnostic core
A tiny zero-dependency fetcher that runs in Node, Bun, Deno, edge workers, or the browser. No React required.
Schema-driven invalidation
Tag routes once and mutations automatically refresh the right queries through a shared TagRegistry.
Optimistic updates that compose
Update multiple caches per mutation with snapshot and rollback semantics built in.
OpenAPI codegen
Generate a typed schema straight from an OpenAPI 3.x spec. Pagination is detected automatically.
Bring your own QueryClient
Reuse one QueryClient across clients, or hook into persistence and devtools — use-q never gets in the way.
Ready to dive in?
Install the packages, define your first schema, and ship a typed list-and-create flow in five minutes.
Read the docs