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

# Quick Start

> Get started with TanStack Query in minutes by building your first query.

# Quick Start

This guide walks you through building your first application with TanStack Query. We'll use React in this example, but the concepts apply to all supported frameworks.

## Prerequisites

Before you begin, make sure you have:

* Node.js installed (version 16 or higher recommended)
* A React application set up (using Vite, Create React App, or Next.js)
* TanStack Query installed (see [Installation](/installation))

## Setup

<Steps>
  <Step title="Create a QueryClient">
    The `QueryClient` manages your queries and cache. Create one at the root of your application:

    ```tsx theme={null}
    import { QueryClient } from '@tanstack/react-query'

    const queryClient = new QueryClient()
    ```

    <Tip>
      You can configure default options for all queries when creating the client:

      ```tsx theme={null}
      const queryClient = new QueryClient({
        defaultOptions: {
          queries: {
            staleTime: 1000 * 60 * 5, // 5 minutes
            gcTime: 1000 * 60 * 60 * 24, // 24 hours
          },
        },
      })
      ```
    </Tip>
  </Step>

  <Step title="Wrap your app with QueryClientProvider">
    The `QueryClientProvider` makes the QueryClient available to your entire component tree:

    ```tsx theme={null}
    import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

    const queryClient = new QueryClient()

    function App() {
      return (
        <QueryClientProvider client={queryClient}>
          {/* Your app components */}
          <Example />
        </QueryClientProvider>
      )
    }
    ```
  </Step>

  <Step title="Create your first query">
    Use the `useQuery` hook to fetch and cache data. You need:

    * A unique `queryKey` to identify the query
    * A `queryFn` that returns a promise

    ```tsx theme={null}
    import { useQuery } from '@tanstack/react-query'

    function Example() {
      const { data, isPending, error } = useQuery({
        queryKey: ['repoData'],
        queryFn: async () => {
          const response = await fetch(
            'https://api.github.com/repos/TanStack/query'
          )
          if (!response.ok) {
            throw new Error('Network response was not ok')
          }
          return response.json()
        },
      })

      if (isPending) return <div>Loading...</div>

      if (error) return <div>An error occurred: {error.message}</div>

      return (
        <div>
          <h1>{data.full_name}</h1>
          <p>{data.description}</p>
          <div>
            <strong>⭐ {data.stargazers_count}</strong>
            <strong> 🍴 {data.forks_count}</strong>
            <strong> 👀 {data.subscribers_count}</strong>
          </div>
        </div>
      )
    }
    ```

    <Note>
      TanStack Query automatically handles:

      * Caching the response
      * Deduplicating identical requests
      * Refetching when the window regains focus
      * Retrying failed requests
      * Updating loading and error states
    </Note>
  </Step>

  <Step title="Add DevTools (Optional)">
    The DevTools help you visualize and debug your queries during development:

    ```tsx theme={null}
    import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
    import { ReactQueryDevtools } from '@tanstack/react-query-devtools'

    const queryClient = new QueryClient()

    function App() {
      return (
        <QueryClientProvider client={queryClient}>
          <Example />
          <ReactQueryDevtools initialIsOpen={false} />
        </QueryClientProvider>
      )
    }
    ```

    <Tip>
      The DevTools are automatically excluded from production builds, so you can safely leave them in your code.
    </Tip>
  </Step>
</Steps>

## Complete Example

Here's the complete working example:

```tsx theme={null}
import React from 'react'
import ReactDOM from 'react-dom/client'
import {
  QueryClient,
  QueryClientProvider,
  useQuery,
} from '@tanstack/react-query'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'

const queryClient = new QueryClient()

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <ReactQueryDevtools />
      <Example />
    </QueryClientProvider>
  )
}

function Example() {
  const { isPending, error, data, isFetching } = useQuery({
    queryKey: ['repoData'],
    queryFn: async () => {
      const response = await fetch(
        'https://api.github.com/repos/TanStack/query'
      )
      return response.json()
    },
  })

  if (isPending) return 'Loading...'

  if (error) return 'An error has occurred: ' + error.message

  return (
    <div>
      <h1>{data.full_name}</h1>
      <p>{data.description}</p>
      <strong>👀 {data.subscribers_count}</strong>{' '}
      <strong>✨ {data.stargazers_count}</strong>{' '}
      <strong>🍴 {data.forks_count}</strong>
      <div>{isFetching ? 'Updating...' : ''}</div>
    </div>
  )
}

const rootElement = document.getElementById('root') as HTMLElement
ReactDOM.createRoot(rootElement).render(<App />)
```

## Understanding the Query Result

The `useQuery` hook returns an object with several useful properties:

* **`data`** - The successfully fetched data (undefined until the query succeeds)
* **`error`** - The error object if the query failed (null if successful)
* **`isPending`** - `true` if the query is currently fetching for the first time
* **`isError`** - `true` if the query encountered an error
* **`isSuccess`** - `true` if the query was successful
* **`isFetching`** - `true` whenever the query is fetching (including background refetches)
* **`refetch`** - A function to manually trigger a refetch

## Query Keys

Query keys uniquely identify your queries. They can be:

```tsx theme={null}
// Simple string key
useQuery({ queryKey: ['todos'], ... })

// Array with multiple values
useQuery({ queryKey: ['todo', todoId], ... })

// Complex nested structure
useQuery({ queryKey: ['todos', { status: 'active', page: 1 }], ... })
```

<Note>
  When any value in the query key changes, TanStack Query automatically refetches the data. This makes dependent queries trivial to implement.
</Note>

## What Happens Automatically?

With zero configuration, TanStack Query:

1. **Caches** your data in memory
2. **Deduplicates** identical requests that happen simultaneously
3. **Refetches** data when the window regains focus
4. **Refetches** data when the network reconnects
5. **Retries** failed requests with exponential backoff
6. **Marks data as stale** after a configurable time period
7. **Garbage collects** unused cache data

## Next Steps

Now that you've built your first query, explore more advanced features:

<CardGroup cols={2}>
  <Card title="Query Options" icon="sliders" href="/concepts/queries">
    Configure caching, refetching, and retry behavior
  </Card>

  <Card title="Mutations" icon="pen" href="/concepts/mutations">
    Learn how to create, update, and delete data
  </Card>

  <Card title="Query Invalidation" icon="refresh" href="/concepts/invalidation">
    Keep your data fresh after mutations
  </Card>

  <Card title="Pagination" icon="list" href="/guides/paginated-queries">
    Implement paginated and infinite scroll queries
  </Card>
</CardGroup>

## Framework-Specific Examples

While this guide uses React, the concepts are identical across frameworks. The main differences are:

* **Vue**: Use `useQuery` from `@tanstack/vue-query` with Vue's Composition API
* **Solid**: Use `createQuery` from `@tanstack/solid-query` as a primitive
* **Svelte**: Use `createQuery` from `@tanstack/svelte-query` with Svelte's reactive syntax
* **Angular**: Use `injectQuery` from `@tanstack/angular-query-experimental` with Signals

Check the framework-specific documentation for detailed examples.
