or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-tanstack--eslint-plugin-query

ESLint plugin for TanStack Query that provides comprehensive linting rules to enforce best practices and prevent common pitfalls.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@tanstack/eslint-plugin-query@5.86.x

To install, run

npx @tessl/cli install tessl/npm-tanstack--eslint-plugin-query@5.86.0

index.mddocs/

@tanstack/eslint-plugin-query

@tanstack/eslint-plugin-query is an ESLint plugin specifically designed for TanStack Query applications. It provides a comprehensive set of linting rules to enforce best practices and prevent common pitfalls when using TanStack Query, helping developers avoid runtime errors and maintain consistent coding patterns.

Package Information

  • Package Name: @tanstack/eslint-plugin-query
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @tanstack/eslint-plugin-query

Core Imports

import queryPlugin from "@tanstack/eslint-plugin-query";
// Named exports also available:
import { Plugin } from "@tanstack/eslint-plugin-query";

For legacy configuration:

const queryPlugin = require("@tanstack/eslint-plugin-query");

Basic Usage

Modern Flat Config (ESLint 9+)

import queryPlugin from "@tanstack/eslint-plugin-query";

export default [
  // Other configs...
  ...queryPlugin.configs["flat/recommended"]
];

Legacy Config (ESLint 8)

module.exports = {
  plugins: ["@tanstack/query"],
  extends: ["plugin:@tanstack/query/recommended"],
  // Or configure individual rules:
  rules: {
    "@tanstack/query/exhaustive-deps": "error",
    "@tanstack/query/no-rest-destructuring": "warn",
    "@tanstack/query/stable-query-client": "error",
  }
};

Capabilities

Plugin Structure

Main plugin object with rules and configurations.

interface Plugin extends Omit<ESLint.Plugin, 'rules'> {
  rules: Record<RuleKey, RuleModule<any, any, any>>;
  configs: {
    recommended: ESLint.ConfigData;
    'flat/recommended': Array<Linter.Config>;
  };
}

const plugin: Plugin;
export default plugin;

Configuration Presets

Pre-configured rule sets for immediate use.

// Legacy configuration format
interface RecommendedConfig {
  plugins: string[];
  rules: {
    '@tanstack/query/exhaustive-deps': 'error';
    '@tanstack/query/no-rest-destructuring': 'warn';
    '@tanstack/query/stable-query-client': 'error';
    '@tanstack/query/no-unstable-deps': 'error';
    '@tanstack/query/infinite-query-property-order': 'error';
    '@tanstack/query/no-void-query-fn': 'error';
    '@tanstack/query/mutation-property-order': 'error';
  };
}

// Modern flat configuration format  
interface FlatRecommendedConfig extends Array<{
  name: string;
  plugins: Record<string, Plugin>;
  rules: Record<string, string>;
}> {}

ESLint Rules

Collection of seven specialized linting rules for TanStack Query applications.

Exhaustive Dependencies Rule

Ensures all dependencies used in queryFn are included in queryKey to prevent stale closure issues.

// Rule: @tanstack/query/exhaustive-deps
// Severity: error
// Description: Exhaustive deps rule for useQuery
// Provides auto-fix suggestions for missing dependencies

Usage Example:

// ❌ Bad - missing dependencies in queryKey
useQuery({
  queryKey: ['user'],
  queryFn: () => fetchUser(userId, settings), // userId and settings not in queryKey
});

// ✅ Good - all dependencies included
useQuery({
  queryKey: ['user', userId, settings],
  queryFn: () => fetchUser(userId, settings),
});

No Rest Destructuring Rule

Disallows rest destructuring in queries to prevent excessive re-renders.

// Rule: @tanstack/query/no-rest-destructuring
// Severity: warn  
// Description: Disallows rest destructuring in queries

Usage Example:

// ❌ Bad - rest destructuring can cause issues
const { data, ...rest } = useQuery({ queryKey: ['user'], queryFn: fetchUser });

// ✅ Good - explicit destructuring
const { data, isLoading, error } = useQuery({ queryKey: ['user'], queryFn: fetchUser });

Stable Query Client Rule

Makes sure that QueryClient is stable to prevent unnecessary re-renders.

// Rule: @tanstack/query/stable-query-client
// Severity: error
// Description: Makes sure that QueryClient is stable

Usage Example:

// ❌ Bad - creating new QueryClient instance on each render
function App() {
  return (
    <QueryClientProvider client={new QueryClient()}>
      <MyComponent />
    </QueryClientProvider>
  );
}

// ✅ Good - stable QueryClient instance
const queryClient = new QueryClient();
function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <MyComponent />
    </QueryClientProvider>
  );
}

No Unstable Dependencies Rule

Disallows putting the result of query hooks directly in a React hook dependency array to prevent infinite re-render loops.

// Rule: @tanstack/query/no-unstable-deps  
// Severity: error
// Description: Disallow putting the result of query hooks directly in a React hook dependency array

Usage Example:

// ❌ Bad - using query result directly in dependency array
const { data: user } = useQuery({ queryKey: ['user'], queryFn: fetchUser });
useEffect(() => {
  console.log('User changed');
}, [user]); // This causes infinite re-renders

// ✅ Good - use specific properties or data content
useEffect(() => {
  console.log('User changed');
}, [user?.id]); // Only re-run when user ID changes

Infinite Query Property Order Rule

Ensures correct order of inference sensitive properties for infinite queries.

// Rule: @tanstack/query/infinite-query-property-order
// Severity: error  
// Description: Ensure correct order of inference sensitive properties for infinite queries

Usage Example:

// ✅ Good - properties in correct order
useInfiniteQuery({
  queryKey: ['posts'],
  queryFn: fetchPosts,
  initialPageParam: 0,
  getNextPageParam: (lastPage) => lastPage.nextCursor,
});

No Void Query Function Rule

Ensures queryFn returns a non-undefined value to prevent runtime issues.

// Rule: @tanstack/query/no-void-query-fn
// Severity: error
// Description: Ensures queryFn returns a non-undefined value

Usage Example:

// ❌ Bad - query function returns void
useQuery({
  queryKey: ['user'],
  queryFn: () => { console.log('fetching'); }, // returns void
});

// ✅ Good - query function returns data
useQuery({
  queryKey: ['user'], 
  queryFn: () => fetchUser(), // returns Promise<User>
});

Mutation Property Order Rule

Ensures correct order of inference-sensitive properties in useMutation().

// Rule: @tanstack/query/mutation-property-order
// Severity: error
// Description: Ensure correct order of inference-sensitive properties in useMutation()

Usage Example:

// ✅ Good - properties in correct order
useMutation({
  mutationFn: updateUser,
  onSuccess: (data) => {
    queryClient.invalidateQueries({ queryKey: ['user'] });
  },
  onError: (error) => {
    console.error('Update failed:', error);
  },
});

Types

import type { ESLint, Linter } from 'eslint';
import type { RuleModule } from '@typescript-eslint/utils/ts-eslint';

type RuleKey = keyof typeof rules;

interface Plugin extends Omit<ESLint.Plugin, 'rules'> {
  rules: Record<RuleKey, RuleModule<any, any, any>>;
  configs: {
    recommended: ESLint.ConfigData;
    'flat/recommended': Array<Linter.Config>;
  };
}

type ExtraRuleDocs = {
  recommended: 'strict' | 'error' | 'warn';
}

Framework Compatibility

This ESLint plugin works with all TanStack Query framework adapters and automatically detects the correct query hooks from:

  • React: @tanstack/react-query
  • Vue: @tanstack/vue-query
  • Solid: @tanstack/solid-query
  • Svelte: @tanstack/svelte-query
  • Angular: @tanstack/angular-query-experimental

The plugin uses intelligent import detection and only applies rules to code that uses TanStack Query hooks.

Error Handling

The plugin automatically detects TanStack Query imports and only applies rules to relevant code. Rules provide detailed error messages and auto-fix suggestions where possible. If you encounter false positives, ensure your TanStack Query imports follow standard patterns:

// Supported import patterns
import { useQuery } from '@tanstack/react-query';
import { useQuery } from '@tanstack/vue-query';  
import { useQuery } from '@tanstack/solid-query';
import { useQuery } from '@tanstack/svelte-query';

TypeScript Integration

The plugin includes full TypeScript definitions and integrates seamlessly with TypeScript ESLint parser. When using TypeScript, the plugin can provide enhanced type-aware linting for improved accuracy.