---
url: https://openapi-typesafe.github.io/openapi-typesafe/react-query.md
description: Type-safe TanStack Query hooks generated from your OpenAPI schema
---

# Introduction

openapi-typesafe-react-query is a type-safe tiny wrapper (about 1 kB minified) around [@tanstack/react-query](https://tanstack.com/query/latest/docs/framework/react/overview) to work with OpenAPI schema.

It works by using [openapi-typesafe-fetch](../fetch/) and [openapi-typesafe](../introduction) so you get all the following features:

* No typos in URLs or params.
* All parameters, request bodies, and responses are type-checked against your schema
* No manual typing of your API
* Eliminates `any` types that hide bugs
* Also eliminates `as` type overrides that can also hide bugs

::: code-group

```tsx [src/my-component.ts]
import createFetchClient from "openapi-typesafe-fetch";
import createClient from "openapi-typesafe-react-query";
import type { paths } from "./my-openapi-3-schema"; // generated by openapi-typesafe

const fetchClient = createFetchClient<paths>({
  baseUrl: "https://myapi.dev/v1/",
});
const $api = createClient(fetchClient);

const MyComponent = () => {
  const { data, error, isLoading } = $api.useQuery(
    "get",
    "/blogposts/{post_id}",
    {
      params: {
        path: { post_id: "5" },
      },
    },
  );

  if (error) return `An error occurred: ${error.message}`;

  if (isLoading || !data) return "Loading...";

  return <div>{data.title}</div>;
};
```

:::

## Setup

Install this library along with [openapi-typesafe-fetch](../fetch/) and [openapi-typesafe](../introduction):

```bash
npm i openapi-typesafe-react-query openapi-typesafe-fetch @tanstack/react-query
npm i -D openapi-typesafe typescript
```

The hooks call TanStack Query's own hooks, which read a `QueryClient` from a
`QueryClientProvider`. `createClient` gives you the typed hooks (`$api`), not a `QueryClient`, so
you need both: create the `QueryClient` once and wrap your app in its provider.

::: code-group

```tsx [src/main.tsx]
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

const queryClient = new QueryClient();

export function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <MyComponent />
    </QueryClientProvider>
  );
}
```

:::

Without a provider every hook throws `No QueryClient set, use QueryClientProvider to set one`;
you can also pass a `QueryClient` as the last argument of each hook. If you get that error with a
provider in place, two copies of `@tanstack/react-query` are installed (`npm ls
@tanstack/react-query`): it is a peer dependency, so the app and this package must share one.

::: tip Highly recommended

Enable [noUncheckedIndexedAccess](https://www.typescriptlang.org/tsconfig#noUncheckedIndexedAccess) in your `tsconfig.json` ([docs](/advanced#enable-nouncheckedindexedaccess-in-tsconfig))

:::

Next, generate TypeScript types from your OpenAPI schema using openapi-typesafe:

```bash
npx openapi-typesafe ./path/to/api/v1.yaml -o ./src/lib/api/v1.d.ts
```

## Basic usage

Once your types have been generated from your schema, you can create a [fetch client](../fetch/), a react-query client and start querying your API.

::: code-group

```tsx [src/my-component.ts]
import createFetchClient from "openapi-typesafe-fetch";
import createClient from "openapi-typesafe-react-query";
import type { paths } from "./my-openapi-3-schema"; // generated by openapi-typesafe

const fetchClient = createFetchClient<paths>({
  baseUrl: "https://myapi.dev/v1/",
});
const $api = createClient(fetchClient);

const MyComponent = () => {
  const { data, error, isLoading } = $api.useQuery(
    "get",
    "/blogposts/{post_id}",
    {
      params: {
        path: { post_id: "5" },
      },
    },
  );

  if (error) return `An error occurred: ${error.message}`;

  if (isLoading || !data) return "Loading...";

  return <div>{data.title}</div>;
};
```

:::

::: tip
You can find more information about `createFetchClient` on the [openapi-typesafe-fetch documentation](../fetch/index.md).
:::
