Try @eslint-react/kit@beta
logoESLint React

Recipes

Ready-to-use custom ESLint rule definitions built with @eslint-react/kit

Recipes are ready-to-use custom ESLint rule definitions built with @eslint-react/kit. They are not part of the core plugin. Instead, they are designed to be copied and pasted directly into your project. Each recipe contains one or more custom rules.

Why Recipes?

Some lint rules are inherently opinionated. They enforce a specific code style or convention that not every team agrees on. Rather than shipping these as built-in rules with fixed behavior, we provide them as recipes so you can:

  • Copy the rule definition into your project.
  • Customize the implementation to match your team's conventions.
  • Own the code with no dependency on upstream changes you didn't ask for.

Prerequisites

Recipes require the @eslint-react/kit package:

npm install --save-dev @eslint-react/kit

Usage

Each recipe page provides:

  1. Rule: A self-contained function you copy into your project (e.g. into a .config/noForwardRef.ts file).
  2. Config: How to wire it up in your eslint.config.ts using eslintReactKit().use(...).
  3. Examples: Code snippets demonstrating valid and invalid patterns to show what the rule catches and how to resolve it.

Here's the general pattern:

.config/noForwardRef.ts
import type { RuleFunction } from "@eslint-react/kit";

function noForwardRef(): RuleFunction {
  return (context, { is }) => ({
    CallExpression(node) {
      if (is.forwardRefCall(node)) {
        context.report({ node, message: "The 'forwardRef' is deprecated in React 19. Pass 'ref' as a prop instead." });
      }
    },
  });
}
eslint.config.ts
import eslintReact from "@eslint-react/eslint-plugin";
import eslintReactKit from "@eslint-react/kit";
import eslintJs from "@eslint/js";
import { defineConfig } from "eslint/config";
import tseslint from "typescript-eslint";

import { noForwardRef } from "./.config/noForwardRef";

export default defineConfig(
  {
    files: ["**/*.{ts,tsx}"],
    extends: [
      eslintJs.configs.recommended,
      tseslint.configs.recommended,
      eslintReact.configs["recommended-typescript"],
      eslintReactKit()
        .use(noForwardRef)
        .getConfig(),
    ],
    rules: {
      "@eslint-react/kit/no-forward-ref": "error",
    },
  },
);

Available Recipes

Simple

Single-purpose recipes containing one custom rule for a specific linting need.

RecipeDescription
Function Component DefinitionEnforces arrow function style for function component definitions.
No Circular EffectDetects circular dependencies between useEffect hooks. Prevents infinite update loops caused by effects that set state they also depend on.
No Multiple Children in TitleEnsures the <title> component has a single string child to avoid React errors.
Prefer Namespace ImportEnforces importing React via a namespace import instead of default import.

Compound

Multi-rule recipes that bundle related rules around a specific domain (props, state, children, context).

RecipeRulesDescription
Custom Rules Of Props4Validates JSX props. Includes checks for duplicate props, mixing controlled and uncontrolled props, explicit spread props, and direct props access.
Custom Rules Of State1Validates state usage. Prefer the updater function form in useState setters.
Custom Rules Of Context1Validates React Context API usage. Includes checks for useContext and other context-related patterns.
Custom Rules Of Children5Validates React Children API usage.

Resources

  • AST Explorer - A tool for exploring the abstract syntax tree (AST) of JavaScript code, which is essential for writing custom rules.
  • ESLint Developer Guide - Official ESLint documentation for creating custom rules.
  • Using the TypeScript Compiler API - TypeScript compiler API documentation for working with type information in custom rules.

On this page