Skip to main content

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.

1

Install

Add the adapter and its peer dependencies to your project.
npm install @convex-dev/react-query @tanstack/react-query convex
2

Create ConvexQueryClient

Initialize the Convex client, the ConvexQueryClient adapter, and the TanStack QueryClient together. Do this once at the module level, outside any component.
import { ConvexReactClient } from "convex/react";
import { QueryClient } from "@tanstack/react-query";
import { ConvexQueryClient } from "@convex-dev/react-query";

const convexClient = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL);
const convexQueryClient = new ConvexQueryClient(convexClient);
const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      queryKeyHashFn: convexQueryClient.hashFn(),
      queryFn: convexQueryClient.queryFn(),
    },
  },
});
convexQueryClient.connect(queryClient);
The queryKeyHashFn must be set globally — it cannot be set per-query, so the client can correctly identify and update Convex query cache entries.
3

Wrap your app

Place ConvexProvider and QueryClientProvider around your application. Both providers are required: ConvexProvider enables Convex hooks like useConvexMutation, while QueryClientProvider makes the TanStack cache available to useQuery.
import { ConvexProvider } from "convex/react";
import { QueryClientProvider } from "@tanstack/react-query";

function Main() {
  return (
    <ConvexProvider client={convexClient}>
      <QueryClientProvider client={queryClient}>
        <App />
      </QueryClientProvider>
    </ConvexProvider>
  );
}
4

Make your first reactive query

Use convexQuery() as the options argument to useQuery. Pass your generated api object and any query arguments.
import { useQuery } from "@tanstack/react-query";
import { convexQuery } from "@convex-dev/react-query";
import { api } from "../convex/_generated/api";

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

  if (isPending) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;
  return (
    <ul>
      {data.map((message) => (
        <li key={message._id}>{message.body}</li>
      ))}
    </ul>
  );
}
The query subscribes via WebSocket and updates automatically whenever the server data changes. No polling needed.

Next steps

Reactive queries

Learn how to use convexQuery with conditional queries, useSuspenseQuery, and custom options like placeholderData.

Mutations & actions

Use useConvexMutation and useConvexAction with TanStack Query’s useMutation hook.

Authentication

Integrate Convex Auth, Clerk, or another auth provider with the query adapter.

API reference

Full reference for ConvexQueryClient, convexQuery, convexAction, and all re-exported hooks.

Build docs developers (and LLMs) love