The framework agnostic core that powers TanStack Query for data fetching and caching
—
Core query functionality providing data fetching, caching, invalidation, and state management with automatic background updates and intelligent cache strategies.
Direct query execution methods for fetching data outside of observers.
/**
* Fetch a query imperatively and return the data
* Creates or reuses existing query in cache
* @param options - Query configuration including key and function
* @returns Promise resolving to query data
*/
fetchQuery<T>(options: FetchQueryOptions<T>): Promise<T>;
/**
* Prefetch a query without subscribing to it
* Useful for loading data before it's needed
* @param options - Query configuration including key and function
* @returns Promise that resolves when prefetch completes
*/
prefetchQuery<T>(options: FetchQueryOptions<T>): Promise<void>;
/**
* Ensure query data exists, fetching if necessary
* Won't refetch if data is fresh unless revalidateIfStale is true
* @param options - Query configuration with revalidation options
* @returns Promise resolving to existing or fetched data
*/
ensureQueryData<T>(options: EnsureQueryDataOptions<T>): Promise<T>;
interface FetchQueryOptions<T> {
queryKey: QueryKey;
queryFn?: QueryFunction<T>;
staleTime?: number;
gcTime?: number;
retry?: RetryValue<T>;
networkMode?: NetworkMode;
initialData?: T | InitialDataFunction<T>;
initialDataUpdatedAt?: number | (() => number | undefined);
meta?: QueryMeta;
signal?: AbortSignal;
}
interface EnsureQueryDataOptions<T> extends FetchQueryOptions<T> {
revalidateIfStale?: boolean;
}Usage Examples:
import { QueryClient } from "@tanstack/query-core";
const queryClient = new QueryClient();
// Basic fetch
const user = await queryClient.fetchQuery({
queryKey: ['user', 123],
queryFn: async () => {
const response = await fetch('/api/user/123');
return response.json();
},
});
// Prefetch for later use
await queryClient.prefetchQuery({
queryKey: ['posts', 'popular'],
queryFn: async () => {
const response = await fetch('/api/posts/popular');
return response.json();
},
staleTime: 5 * 60 * 1000, // 5 minutes
});
// Ensure data exists
const userData = await queryClient.ensureQueryData({
queryKey: ['user', 123],
queryFn: async () => {
const response = await fetch('/api/user/123');
return response.json();
},
revalidateIfStale: true,
});Methods for managing query state and triggering updates.
/**
* Invalidate queries matching the filters
* Marks queries as stale and triggers refetch for active queries
* @param filters - Query filters to match against
* @param options - Invalidation options
* @returns Promise that resolves when invalidation completes
*/
invalidateQueries(
filters?: InvalidateQueryFilters,
options?: InvalidateOptions
): Promise<void>;
/**
* Refetch queries matching the filters
* Forces immediate refetch regardless of staleness
* @param filters - Query filters to match against
* @param options - Refetch options
* @returns Promise that resolves when refetch completes
*/
refetchQueries(
filters?: RefetchQueryFilters,
options?: RefetchOptions
): Promise<void>;
/**
* Cancel ongoing queries matching the filters
* Aborts network requests and resets loading states
* @param filters - Query filters to match against
* @param options - Cancellation options
* @returns Promise that resolves when cancellation completes
*/
cancelQueries(filters?: QueryFilters, options?: CancelOptions): Promise<void>;
/**
* Remove queries from cache matching the filters
* Permanently removes queries and their cached data
* @param filters - Query filters to match against
*/
removeQueries(filters?: QueryFilters): void;
/**
* Reset queries to their initial state
* Clears data and error state, triggers refetch for active queries
* @param filters - Query filters to match against
* @param options - Reset options
* @returns Promise that resolves when reset completes
*/
resetQueries(filters?: QueryFilters, options?: ResetOptions): Promise<void>;
interface InvalidateQueryFilters extends QueryFilters {
refetchType?: 'active' | 'inactive' | 'all' | 'none';
}
interface RefetchQueryFilters extends QueryFilters {
type?: 'active' | 'inactive' | 'all';
}
interface InvalidateOptions {
refetchType?: 'active' | 'inactive' | 'all' | 'none';
}
interface RefetchOptions extends CancelOptions {
throwOnError?: boolean;
}
interface CancelOptions {
revert?: boolean;
silent?: boolean;
}
interface ResetOptions extends RefetchOptions {}Usage Examples:
// Invalidate all user queries
await queryClient.invalidateQueries({
queryKey: ['user'],
});
// Invalidate exact query
await queryClient.invalidateQueries({
queryKey: ['user', 123],
exact: true,
});
// Refetch only active queries
await queryClient.refetchQueries({
queryKey: ['posts'],
type: 'active',
});
// Cancel all ongoing fetches
await queryClient.cancelQueries();
// Remove stale queries
queryClient.removeQueries({
stale: true,
});
// Reset specific query
await queryClient.resetQueries({
queryKey: ['user', 123],
exact: true,
});Methods for directly manipulating cached query data.
/**
* Get cached data for a specific query
* @param queryKey - The query key to retrieve data for
* @returns The cached data or undefined if not found
*/
getQueryData<T>(queryKey: QueryKey): T | undefined;
/**
* Set or update cached data for a specific query
* @param queryKey - The query key to set data for
* @param updater - New data or function to update existing data
* @param options - Additional options for setting data
* @returns The updated data
*/
setQueryData<T>(
queryKey: QueryKey,
updater: Updater<T>,
options?: SetDataOptions
): T | undefined;
/**
* Get cached data for multiple queries matching filters
* @param filters - Query filters to match against
* @returns Array of [queryKey, data] tuples
*/
getQueriesData<T>(filters: QueryFilters): Array<[QueryKey, T | undefined]>;
/**
* Set cached data for multiple queries matching filters
* @param filters - Query filters to match against
* @param updater - New data or function to update existing data
* @param options - Additional options for setting data
* @returns Array of [queryKey, data] tuples
*/
setQueriesData<T>(
filters: QueryFilters,
updater: Updater<T>,
options?: SetDataOptions
): Array<[QueryKey, T | undefined]>;
interface SetDataOptions {
updatedAt?: number;
}Usage Examples:
// Get cached data
const userData = queryClient.getQueryData(['user', 123]);
// Set data with new value
queryClient.setQueryData(['user', 123], {
id: 123,
name: 'John Doe',
email: 'john@example.com',
});
// Update data functionally
queryClient.setQueryData(['user', 123], (oldData) => ({
...oldData,
lastSeen: new Date().toISOString(),
}));
// Get data from multiple queries
const allUserData = queryClient.getQueriesData({
queryKey: ['user'],
});
// Update multiple queries
queryClient.setQueriesData(
{ queryKey: ['user'] },
(oldData) => ({ ...oldData, updated: true })
);Methods for accessing detailed query state information.
/**
* Get the complete state for a specific query
* @param queryKey - The query key to get state for
* @returns The query state or undefined if not found
*/
getQueryState<T>(queryKey: QueryKey): QueryState<T> | undefined;
interface QueryState<TData = unknown, TError = Error> {
data: TData | undefined;
dataUpdateCount: number;
dataUpdatedAt: number;
error: TError | null;
errorUpdateCount: number;
errorUpdatedAt: number;
fetchFailureCount: number;
fetchFailureReason: TError | null;
fetchMeta: FetchMeta | null;
isInvalidated: boolean;
status: QueryStatus;
fetchStatus: FetchStatus;
}Usage Examples:
// Get complete query state
const queryState = queryClient.getQueryState(['user', 123]);
if (queryState) {
console.log('Data:', queryState.data);
console.log('Status:', queryState.status);
console.log('Last updated:', new Date(queryState.dataUpdatedAt));
console.log('Error count:', queryState.fetchFailureCount);
console.log('Is invalidated:', queryState.isInvalidated);
}interface QueryFilters {
/**
* Query key to match against
* Can be exact match or partial match depending on 'exact' option
*/
queryKey?: QueryKey;
/**
* Whether to match the query key exactly
* If false, performs partial matching
*/
exact?: boolean;
/**
* Filter by stale status
* true: only stale queries, false: only fresh queries
*/
stale?: boolean;
/**
* Filter by active status (has active observers)
* true: only active queries, false: only inactive queries
*/
active?: boolean;
/**
* Filter by inactive status (no active observers)
* true: only inactive queries, false: only active queries
*/
inactive?: boolean;
/**
* Custom predicate function for advanced filtering
* @param query - The query to test
* @returns true if query matches filter
*/
predicate?: (query: Query) => boolean;
/**
* Filter by fetch status
*/
fetchStatus?: FetchStatus;
/**
* Filter by query type
*/
type?: QueryTypeFilter;
}
type QueryTypeFilter = 'all' | 'active' | 'inactive';type QueryKey = ReadonlyArray<unknown>;
type QueryFunction<T = unknown, TQueryKey extends QueryKey = QueryKey> = (
context: QueryFunctionContext<TQueryKey>
) => T | Promise<T>;
interface QueryFunctionContext<TQueryKey extends QueryKey = QueryKey> {
queryKey: TQueryKey;
signal: AbortSignal;
meta: QueryMeta | undefined;
pageParam?: unknown;
direction?: 'forward' | 'backward';
}
type QueryStatus = 'pending' | 'error' | 'success';
type FetchStatus = 'fetching' | 'paused' | 'idle';
type NetworkMode = 'online' | 'always' | 'offlineFirst';
type RetryValue<TError> = boolean | number | ((failureCount: number, error: TError) => boolean);
type InitialDataFunction<T> = () => T | undefined;
interface QueryMeta extends Record<string, unknown> {}
interface FetchMeta extends Record<string, unknown> {}
type Updater<T> = T | ((old: T) => T);Install with Tessl CLI
npx tessl i tessl/npm-tanstack--query-core