---
title: "TanStack Query v5 Plugin"
description: "Generate TanStack Query v5 functions and query keys from OpenAPI with the TanStack Query plugin for openapi-ts. Fully compatible with validators, transformers, and all core features."
url: "https://heyapi.dev/docs/openapi/typescript/plugins/tanstack-query"
---

### About

[Section titled “About”](#about)

[TanStack Query](https://tanstack.com/query) is a powerful asynchronous state management solution for TypeScript/JavaScript, React, Solid, Vue, Svelte, Angular, and Preact.

The TanStack Query plugin for Hey API generates functions and query keys from your OpenAPI spec, fully compatible with SDKs, transformers, and all core features.

### Demo

[Section titled “Demo”](#demo)

Launch demo

## Features

[Section titled “Features”](#features)

* TanStack Query v5 support
* seamless integration with `@hey-api/openapi-ts` ecosystem
* create query keys following the best practices
* type-safe query options, infinite query options, and mutation options
* minimal learning curve thanks to extending the underlying technology

## Installation

[Section titled “Installation”](#installation)

In your [configuration](https://heyapi.dev/openapi-ts/get-started), add TanStack Query to your plugins and you’ll be ready to generate TanStack Query artifacts. 🎉

* react

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      '@tanstack/react-query',
    ],
  };
  ```

* vue

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      '@tanstack/vue-query',
    ],
  };
  ```

* angular

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      '@tanstack/angular-query-experimental',
    ],
  };
  ```

* svelte

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      '@tanstack/svelte-query',
    ],
  };
  ```

* solid

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      '@tanstack/solid-query',
    ],
  };
  ```

* preact

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      '@tanstack/preact-query',
    ],
  };
  ```

## Output

[Section titled “Output”](#output)

The TanStack Query plugin will generate the following artifacts, depending on the input specification.

## Queries

[Section titled “Queries”](#queries)

Queries are generated from [query operations](https://heyapi.dev/openapi-ts/configuration/parser#hooks-query-operations). The generated query functions follow the naming convention of SDK functions and by default append `Options`, e.g., `getPetByIdOptions()`.

* example

  react-query.gen.ts

  ```ts
  const query = useQuery({
    ...getPetByIdOptions({
      path: {
        petId: 1,
      },
    }),
  });
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: '@tanstack/react-query',
        queryOptions: true,
      },
    ],
  };
  ```

You can customize the naming and casing pattern for `queryOptions` functions using the `.name` and `.case` options.

### Meta

[Section titled “Meta”](#meta)

You can use the `meta` field to attach arbitrary information to a query. To generate metadata for `queryOptions`, provide a function to the `.meta` option.

* example

  react-query.gen.ts

  ```ts
  queryOptions({
    // ...other fields
    meta: {
      id: 'getPetById',
    },
  });
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: '@tanstack/react-query',
        queryOptions: {
          meta: (operation) => ({ id: operation.id }),
        },
      },
    ],
  };
  ```

## Query Keys

[Section titled “Query Keys”](#query-keys)

Query keys contain normalized SDK function parameters and additional metadata.

* example

  react-query.gen.ts

  ```ts
  const queryKey = [
    {
      _id: 'getPetById',
      baseUrl: 'https://app.heyapi.dev',
      path: {
        petId: 1,
      },
    },
  ];
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: '@tanstack/react-query',
        queryKeys: true,
      },
    ],
  };
  ```

### Tags

[Section titled “Tags”](#tags)

You can include operation tags in your query keys by setting `tags` to `true`. This will make query keys larger but provides better cache invalidation capabilities.

* example

  react-query.gen.ts

  ```ts
  const queryKey = [
    {
      _id: 'getPetById',
      baseUrl: 'https://app.heyapi.dev',
      path: {
        petId: 1,
      },
      tags: ['pets', 'one', 'get'],
    },
  ];
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: '@tanstack/react-query',
        queryKeys: {
          tags: true,
        },
      },
    ],
  };
  ```

### Accessing Query Keys

[Section titled “Accessing Query Keys”](#accessing-query-keys)

If you have access to the result of query options function, you can get the query key from the `queryKey` field.

* example

  react-query.gen.ts

  ```ts
  const { queryKey } = getPetByIdOptions({
    path: {
      petId: 1,
    },
  });
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: '@tanstack/react-query',
        queryOptions: true,
      },
    ],
  };
  ```

Alternatively, you can access the same query key by calling query key functions. The generated query key functions follow the naming convention of SDK functions and by default append `QueryKey`, e.g., `getPetByIdQueryKey()`.

* example

  react-query.gen.ts

  ```ts
  const queryKey = getPetByIdQueryKey({
    path: {
      petId: 1,
    },
  });
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: '@tanstack/react-query',
        queryKeys: true,
      },
    ],
  };
  ```

You can customize the naming and casing pattern for `queryKeys` functions using the `.name` and `.case` options.

## Infinite Queries

[Section titled “Infinite Queries”](#infinite-queries)

Infinite queries are generated from [query operations](https://heyapi.dev/openapi-ts/configuration/parser#hooks-query-operations) if we detect a [pagination](https://heyapi.dev/openapi-ts/configuration/parser#pagination) parameter. The generated infinite query functions follow the naming convention of SDK functions and by default append `InfiniteOptions`, e.g., `getFooInfiniteOptions()`.

* example

  react-query.gen.ts

  ```ts
  const query = useInfiniteQuery({
    ...getFooInfiniteOptions({
      path: {
        fooId: 1,
      },
    }),
    getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
    initialPageParam: 0,
  });
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: '@tanstack/react-query',
        infiniteQueryOptions: true,
      },
    ],
  };
  ```

You can customize the naming and casing pattern for `infiniteQueryOptions` functions using the `.name` and `.case` options.

### Meta

[Section titled “Meta”](#meta-1)

You can use the `meta` field to attach arbitrary information to a query. To generate metadata for `infiniteQueryOptions`, provide a function to the `.meta` option.

* example

  react-query.gen.ts

  ```ts
  infiniteQueryOptions({
    // ...other fields
    meta: {
      id: 'getPetById',
    },
  });
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: '@tanstack/react-query',
        infiniteQueryOptions: {
          meta: (operation) => ({ id: operation.id }),
        },
      },
    ],
  };
  ```

## Infinite Query Keys

[Section titled “Infinite Query Keys”](#infinite-query-keys)

Infinite query keys contain normalized SDK function parameters and additional metadata.

* example

  react-query.gen.ts

  ```ts
  const queryKey = [
    {
      _id: 'getPetById',
      _infinite: true,
      baseUrl: 'https://app.heyapi.dev',
      path: {
        petId: 1,
      },
    },
  ];
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: '@tanstack/react-query',
        infiniteQueryKeys: true,
      },
    ],
  };
  ```

### Tags

[Section titled “Tags”](#tags-1)

You can include operation tags in your infinite query keys by setting `tags` to `true`. This will make query keys larger but provides better cache invalidation capabilities.

* example

  react-query.gen.ts

  ```ts
  const queryKey = [
    {
      _id: 'getPetById',
      _infinite: true,
      baseUrl: 'https://app.heyapi.dev',
      path: {
        petId: 1,
      },
      tags: ['pets', 'one', 'get'],
    },
  ];
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: '@tanstack/react-query',
        infiniteQueryKeys: {
          tags: true,
        },
      },
    ],
  };
  ```

### Accessing Infinite Query Keys

[Section titled “Accessing Infinite Query Keys”](#accessing-infinite-query-keys)

If you have access to the result of infinite query options function, you can get the query key from the `queryKey` field.

* example

  react-query.gen.ts

  ```ts
  const { queryKey } = getPetByIdInfiniteOptions({
    path: {
      petId: 1,
    },
  });
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: '@tanstack/react-query',
        infiniteQueryOptions: true,
      },
    ],
  };
  ```

Alternatively, you can access the same query key by calling query key functions. The generated query key functions follow the naming convention of SDK functions and by default append `InfiniteQueryKey`, e.g., `getPetByIdInfiniteQueryKey()`.

* example

  react-query.gen.ts

  ```ts
  const queryKey = getPetByIdInfiniteQueryKey({
    path: {
      petId: 1,
    },
  });
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: '@tanstack/react-query',
        infiniteQueryKeys: true,
      },
    ],
  };
  ```

You can customize the naming and casing pattern for `infiniteQueryKeys` functions using the `.name` and `.case` options.

## Mutations

[Section titled “Mutations”](#mutations)

Mutations are generated from [mutation operations](https://heyapi.dev/openapi-ts/configuration/parser#hooks-mutation-operations). The generated mutation functions follow the naming convention of SDK functions and by default append `Mutation`, e.g., `addPetMutation()`.

* example

  react-query.gen.ts

  ```ts
  const addPet = useMutation({
    ...addPetMutation(),
    onError: (error) => {
      console.log(error);
    },
  });


  addPet.mutate({
    body: {
      name: 'Kitty',
    },
  });
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: '@tanstack/react-query',
        mutationOptions: true,
      },
    ],
  };
  ```

You can customize the naming and casing pattern for `mutationOptions` functions using the `.name` and `.case` options.

### Meta

[Section titled “Meta”](#meta-2)

You can use the `meta` field to attach arbitrary information to a mutation. To generate metadata for `mutationOptions`, provide a function to the `.meta` option.

* example

  react-query.gen.ts

  ```ts
  const mutationOptions = {
    // ...other fields
    meta: {
      id: 'getPetById',
    },
  };
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: '@tanstack/react-query',
        mutationOptions: {
          meta: (operation) => ({ id: operation.id }),
        },
      },
    ],
  };
  ```

## Reactivity

[Section titled “Reactivity”](#reactivity)

In Vue applications, you need to wrap the options functions in [`computed()`](https://vuejs.org/guide/essentials/computed) to make them reactive. Otherwise, TanStack Query won’t know it should execute the query when its dependencies change.

* reactive

  react-query.gen.ts

  ```js
  // ✅ Query will execute on `petId` change
  const query = useQuery(
    computed(() =>
      getPetByIdOptions({
        path: {
          petId: petId.value,
        },
      }),
    ),
  );
  ```

* static

  react-query.gen.ts

  ```js
  // ❌ Query will execute only once
  const query = useQuery(
    getPetByIdOptions({
      path: {
        petId: petId.value,
      },
    }),
  );
  ```

## API

[Section titled “API”](#api)

You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@tanstack/react-query/types.ts) interface.

## Examples

You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
