> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/get-convex/convex-react-query/llms.txt
> Use this file to discover all available pages before exploring further.

# Reactive queries

> Use convexQuery to subscribe to live-updating Convex query results via TanStack Query.

`convexQuery` is a query options factory that wires TanStack Query's `useQuery` to a Convex query function subscription. Results are pushed from the server whenever the underlying data changes — no polling, no `staleTime` expiry, no manual invalidation.

## Basic usage

Pass a function reference from your generated `api` object and its arguments to `convexQuery`, then hand the result directly to `useQuery`.

```tsx theme={null}
import { useQuery } from "@tanstack/react-query";
import { convexQuery } from "@convex-dev/react-query";
import { api } from "../convex/_generated/api";

const { data, isPending, error } = useQuery(
  convexQuery(api.messages.list, {})
);
```

`staleTime` is set to `Infinity` automatically because Convex pushes fresh results proactively — the data is never stale in the traditional polling sense.

## Queries with arguments

Pass an arguments object as the second parameter. The function reference and the arguments together form the query key.

```tsx theme={null}
const { data } = useQuery(
  convexQuery(api.messages.search, { query: searchTerm, limit: 5 })
);
```

## Conditional / skippable queries

Pass the string `"skip"` in place of an arguments object to disable the query conditionally.

```tsx theme={null}
// Pass "skip" to disable the query conditionally
const { data, isPending } = useQuery(
  convexQuery(api.messages.count, shown ? {} : "skip")
);
```

<Note>
  When `"skip"` is passed, `enabled: false` is set automatically and the query
  won't run. No subscription is created and no request is made.
</Note>

## Suspense support

`convexQuery` is compatible with `useSuspenseQuery`. Wrap the component in a `<Suspense>` boundary to handle the loading state declaratively.

```tsx theme={null}
import { useSuspenseQuery } from "@tanstack/react-query";
import { Suspense } from "react";

function MessageCount() {
  const { data } = useSuspenseQuery(convexQuery(api.messages.count, {}));
  return <div>{data} messages</div>;
}

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <MessageCount />
    </Suspense>
  );
}
```

<Note>
  Actions (`convexAction`) cannot be used with `useSuspenseQuery` because they
  are not reactive and do not push updates.
</Note>

## Controlling subscription lifetime

The Convex WebSocket subscription stays active until TanStack Query's `gcTime` elapses after all observers have unmounted. Tune `gcTime` to balance responsiveness against bandwidth usage.

```tsx theme={null}
const { data } = useQuery({
  ...convexQuery(api.messages.list, {}),
  gcTime: 10000, // unsubscribe 10s after all useQuery hooks unmount
});
```

<Info>
  The default `gcTime` in TanStack Query is 5 minutes. For most apps a value of
  a few seconds is a better tradeoff — it lets fast navigation reuse a cached
  result without holding the subscription open indefinitely.
</Info>

## Extra query options

Spread `convexQuery` into an options object to add `initialData`, `placeholderData`, or any other TanStack Query option.

```tsx theme={null}
const { data } = useQuery({
  ...convexQuery(api.messages.list, {}),
  initialData: [],
  placeholderData: [],
});
```

## Using `convexQueryClient.queryOptions()`

`ConvexQueryClient` exposes a `queryOptions()` method that works the same way as `convexQuery` but embeds its own `queryFn` directly, so you don't need to configure a global default `queryFn`.

```tsx theme={null}
const { data } = useQuery(
  convexQueryClient.queryOptions(api.messages.list, {})
);
```

<Note>
  Unlike `convexQuery`, `convexQueryClient.queryOptions()` does NOT require the
  global `queryFn` to be set on the `QueryClient`. Use it when you prefer
  explicit per-query configuration over a global default.
</Note>
