ESLint Plugins
Install and configure ESLint plugins for React, TypeScript, accessibility, Tailwind CSS, and testing.
Search across all documentation pages
Install and configure ESLint plugins for React, TypeScript, accessibility, Tailwind CSS, and testing.
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
Quick-reference recipe card - copy-paste ready.
# Core plugins (most included with next/core-web-vitals)
npm install --save-dev eslint-plugin-react eslint-plugin-react-hooks
# TypeScript
npm install --save-dev @typescript-eslint/eslint-plugin @typescript-eslint/parser
# Imports
npm install --save-dev eslint-plugin-import
# Accessibility
npm install --save-dev eslint-plugin-jsx-a11y
# Tailwind CSS
npm install --save-dev eslint-plugin-tailwindcss
# Testing Library
npm install --save-dev eslint-plugin-testing-libraryWhen to reach for this: When you need rules beyond what next/core-web-vitals provides - Tailwind class ordering, test best practices, or stricter accessibility checks.
// eslint.config.mjs
import { FlatCompat } from "@eslint/eslintrc";
import tailwindcss from "eslint-plugin-tailwindcss";
import { dirname } from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const compat = new FlatCompat({ baseDirectory: __dirname });
const eslintConfig = [
// Next.js presets (includes react, react-hooks, import, jsx-a11y)
...compat.extends("next/core-web-vitals", "next/typescript"),
// Tailwind CSS plugin (flat config native)
...tailwindcss.configs["flat/recommended"],
// Testing Library (only for test files)
{
files: ["**/*.test.{ts,tsx}", "**/*.spec.{ts,tsx}"],
...compat.extends("plugin:testing-library/react")[0],
},
// Custom rule overrides
{
rules: {
// Tailwind
"tailwindcss/classnames-order": "warn",
"tailwindcss/no-custom-classname": "off",
// Accessibility
"jsx-a11y/anchor-is-valid": "warn",
"jsx-a11y/alt-text": "error",
// TypeScript
"@typescript-eslint/no-unused-vars": [
"error",
{ argsIgnorePattern: "^_" },
],
"@typescript-eslint/consistent-type-imports": "error",
// Imports
"import/order": [
"warn",
{
groups: [
"builtin",
"external",
"internal",
["parent", "sibling"],
"index",
"type",
],
"newlines-between": "always",
alphabetize: { order: "asc" },
},
],
},
},
];
export default eslintConfig;What this demonstrates:
react/, jsx-a11y/)next/core-web-vitals already includes eslint-plugin-react, eslint-plugin-react-hooks, eslint-plugin-next, eslint-plugin-import, and eslint-plugin-jsx-a11ytailwindcss and testing-library are added on topconfigs["flat/recommended"] directly; others need FlatCompatPlugin overview:
| Plugin | Namespace | What It Does |
|---|---|---|
eslint-plugin-react | react/ | JSX best practices, component patterns |
eslint-plugin-react-hooks | react-hooks/ | Hook rules and dependency checking |
@typescript-eslint/eslint-plugin | @typescript-eslint/ | TypeScript-specific rules |
eslint-plugin-import | import/ | Import ordering, no duplicates, no unresolved |
eslint-plugin-jsx-a11y | jsx-a11y/ | Accessibility rules for JSX elements |
eslint-plugin-tailwindcss | tailwindcss/ | Class ordering, no contradicting classes |
eslint-plugin-testing-library | testing-library/ | Best practices for Testing Library |
Tailwind plugin key rules:
{
rules: {
"tailwindcss/classnames-order": "warn", // Sort classes
"tailwindcss/no-custom-classname": "off", // Allow custom classes
"tailwindcss/no-contradicting-classname": "error", // Catch p-4 p-8
"tailwindcss/enforces-negative-arbitrary-values": "warn",
},
}Testing Library plugin (scoped to test files):
{
files: ["**/*.test.{ts,tsx}", "**/*.spec.{ts,tsx}"],
rules: {
"testing-library/await-async-queries": "error",
"testing-library/no-debugging-utils": "warn",
"testing-library/no-dom-import": "error",
"testing-library/prefer-screen-queries": "warn",
},
}// @typescript-eslint key rules:
// no-unused-vars - catches unused imports and variables
// no-explicit-any - flags `any` type usage
// consistent-type-imports - enforces `import type { X }` syntax
// no-non-null-assertion - flags `obj!.prop` assertions
// prefer-nullish-coalescing - flags `||` where `??` is safer
// These complement tsconfig strict mode but catch
// different things (patterns vs types)Things that will bite you. Each gotcha includes what goes wrong, why it happens, and the fix.
Duplicate plugin registration - Installing eslint-plugin-react manually when next/core-web-vitals already includes it causes conflicts. Fix: Check what the preset includes before adding plugins. Only add plugins not already bundled.
Tailwind plugin requires config - eslint-plugin-tailwindcss needs to find your tailwind.config.* file. If your config is in a non-standard location, the plugin fails silently. Fix: Set the config option in the plugin settings.
Testing plugin on all files - Applying testing-library rules globally flags non-test code. Fix: Always scope with files: ["**/*.test.*"].
Flat config compatibility - Not all plugins support flat config natively. Some need FlatCompat wrapping, which can cause unexpected behavior. Fix: Check the plugin's README for flat config support and use FlatCompat only when needed.
Performance with many plugins - Each plugin adds parsing and rule-checking time. Five or more plugins can noticeably slow down linting. Fix: Use TIMING=1 npx eslint . to profile which rules are slow and disable any you do not need.
Other ways to solve the same problem - and when each is the better choice.
| Alternative | Use When | Don't Use When |
|---|---|---|
| Biome | You want linting + formatting in one fast tool | You need Tailwind or testing-library rules |
next/core-web-vitals only | The bundled plugins are sufficient for your project | You need Tailwind class ordering or test rules |
oxlint | You want blazing-fast linting with common rules | You need plugin-specific rules (Tailwind, testing) |
eslint-plugin-reacteslint-plugin-react-hookseslint-plugin-nexteslint-plugin-importeslint-plugin-jsx-a11yYou do not need to install these separately.
{
files: ["**/*.test.{ts,tsx}", "**/*.spec.{ts,tsx}"],
rules: {
"testing-library/await-async-queries": "error",
"testing-library/prefer-screen-queries": "warn",
},
}Use the files property to restrict rules to matching globs.
tailwindcss/classnames-order sorts Tailwind classes in the recommended order.tailwindcss/no-contradicting-classname catches conflicts like p-4 p-8.tailwindcss/no-custom-classname flags classes not in the Tailwind config (often turned off).tailwind.config.* in the project root by default.config option in the plugin settings.configs["flat/recommended"] directly.FlatCompat wrapping to work with ESLint 9 flat config.TIMING=1 npx eslint . to find the slowest rules and disable those you do not need."@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
"@typescript-eslint/consistent-type-imports": "error",
"@typescript-eslint/no-explicit-any": "warn",These are included via next/typescript but you can override their severity.
files: ["**/*.test.*", "**/*.spec.*"].react/, @typescript-eslint/, jsx-a11y/, etc.npx eslint --print-config src/app/page.tsx to see all active rules and their sources.jsx-a11y/alt-text requires alt attributes on images.jsx-a11y/anchor-is-valid warns about anchors without valid href.@typescript-eslint catches code patterns (unused vars, floating promises, explicit any).tsconfig strict options catch type-level issues (null checks, implicit any, unchecked index access).Reviewed by Chris St. John·Last updated Jul 16, 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥