ESLint + Prettier Configuration Reference

Type: Software Reference Confidence: 0.93 Sources: 7 Verified: 2026-02-28 Freshness: 2026-02-28

TL;DR

Constraints

Quick Reference

SettingValuePurpose
Config fileeslint.config.mjsFlat config (ESM recommended)
TypeScript plugintypescript-eslint@^8Type-aware linting for TS files
Prettier bridgeeslint-config-prettierDisables conflicting ESLint formatting rules
Alternative bridgeeslint-plugin-prettierRuns Prettier as an ESLint rule (slower)
Prettier config.prettierrcFormatting options
Globals packageglobalsProvides browser, node globals for flat config
Lint commandnpx eslint .Run linting
Format commandnpx prettier --write .Format all files
Check commandnpx prettier --check .Verify formatting without changes
Config validatornpx eslint --print-config file.tsDebug resolved config for a file

Decision Tree

START
├── Using TypeScript?
│   ├── YES → Install typescript-eslint v8 + @eslint/js
│   └── NO → Install @eslint/js only
├── Want Prettier to run inside ESLint?
│   ├── YES → Use eslint-plugin-prettier/recommended (slower, single command)
│   └── NO → Use eslint-config-prettier (faster, two commands)
├── Using React?
│   ├── YES → Add eslint-plugin-react + eslint-plugin-react-hooks
│   └── NO ↓
├── Need type-aware rules?
│   ├── YES → Use tseslint.configs.recommendedTypeChecked + parserOptions.project
│   └── NO → Use tseslint.configs.recommended (faster)
└── DEFAULT → @eslint/js recommended + eslint-config-prettier

Step-by-Step Guide

1. Install dependencies

Install ESLint 9, typescript-eslint 8, Prettier 3, and the config bridge. [src1]

npm install --save-dev eslint @eslint/js typescript-eslint eslint-config-prettier prettier

Verify: npx eslint --version → expected: v9.x.x

2. Create eslint.config.mjs

Create the flat config file in your project root. [src2]

// eslint.config.mjs
import eslint from "@eslint/js";
import tseslint from "typescript-eslint";
import eslintConfigPrettier from "eslint-config-prettier";

export default tseslint.config(
  { ignores: ["dist/", "node_modules/", "coverage/"] },
  eslint.configs.recommended,
  ...tseslint.configs.recommended,
  {
    files: ["**/*.ts", "**/*.tsx"],
    rules: {
      "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
      "@typescript-eslint/consistent-type-imports": "error",
    },
  },
  eslintConfigPrettier, // MUST be last
);

Verify: npx eslint --print-config src/index.ts | grep semi → no semi rule (disabled by Prettier)

3. Create Prettier configuration

Define formatting preferences in .prettierrc. [src5]

{
  "semi": true,
  "singleQuote": true,
  "trailingComma": "all",
  "printWidth": 100,
  "tabWidth": 2,
  "endOfLine": "lf"
}

Verify: npx prettier --check src/ → All matched files use Prettier code style!

4. Add npm scripts

Add convenience scripts to package.json. [src1]

{
  "scripts": {
    "lint": "eslint .",
    "lint:fix": "eslint . --fix",
    "format": "prettier --write .",
    "format:check": "prettier --check .",
    "check": "eslint . && prettier --check ."
  }
}

Code Examples

Flat Config with React + TypeScript

// eslint.config.mjs — React + TypeScript project
import eslint from "@eslint/js";
import tseslint from "typescript-eslint";
import eslintConfigPrettier from "eslint-config-prettier";
import reactPlugin from "eslint-plugin-react";
import reactHooksPlugin from "eslint-plugin-react-hooks";
import globals from "globals";

export default tseslint.config(
  { ignores: ["dist/", "build/", "node_modules/"] },
  eslint.configs.recommended,
  ...tseslint.configs.recommended,
  {
    files: ["**/*.{ts,tsx}"],
    plugins: { react: reactPlugin, "react-hooks": reactHooksPlugin },
    languageOptions: { globals: { ...globals.browser } },
    settings: { react: { version: "detect" } },
    rules: {
      "react/react-in-jsx-scope": "off",
      "react-hooks/rules-of-hooks": "error",
      "react-hooks/exhaustive-deps": "warn",
    },
  },
  eslintConfigPrettier,
);

Flat Config with Node.js Backend

// eslint.config.mjs — Node.js + TypeScript backend
import eslint from "@eslint/js";
import tseslint from "typescript-eslint";
import eslintConfigPrettier from "eslint-config-prettier";
import globals from "globals";

export default tseslint.config(
  { ignores: ["dist/", "node_modules/"] },
  eslint.configs.recommended,
  ...tseslint.configs.recommendedTypeChecked,
  {
    languageOptions: {
      globals: { ...globals.node },
      parserOptions: { projectService: true, tsconfigRootDir: import.meta.dirname },
    },
    rules: {
      "@typescript-eslint/no-floating-promises": "error",
      "@typescript-eslint/no-misused-promises": "error",
    },
  },
  eslintConfigPrettier,
);

Anti-Patterns

Wrong: Putting eslint-config-prettier before other configs

// ❌ BAD — Prettier config is overridden by later configs
export default [
  eslintConfigPrettier,           // Too early!
  eslint.configs.recommended,     // Re-enables formatting rules
];

Correct: eslint-config-prettier always last

// ✅ GOOD — Prettier config last, disables all formatting rules
export default [
  eslint.configs.recommended,
  ...tseslint.configs.recommended,
  eslintConfigPrettier,           // Last
];

Wrong: Mixing ESLint formatting rules with Prettier

// ❌ BAD — ESLint formatting rules conflict with Prettier
{ rules: { "semi": ["error", "never"], "quotes": ["error", "double"] } }

Correct: Let Prettier handle all formatting

// ✅ GOOD — Only logic rules in ESLint, formatting in .prettierrc
{ rules: { "no-console": "warn", "prefer-const": "error" } }

Common Pitfalls

Diagnostic Commands

# Check ESLint version
npx eslint --version

# Print resolved config for a specific file
npx eslint --print-config src/index.ts

# Find rules conflicting with Prettier
npx eslint-config-prettier src/index.ts

# Check Prettier version
npx prettier --version

# Test Prettier formatting on a single file
npx prettier --check src/index.ts

Version History & Compatibility

VersionStatusBreaking ChangesMigration Notes
ESLint 9.xCurrentFlat config default, .eslintrc deprecatedUse eslint.config.mjs
typescript-eslint 8.xCurrentSingle package, flat config APIReplace @typescript-eslint/* with typescript-eslint
Prettier 3.xCurrentESM-only, async API
ESLint 8.xMaintenanceMigrate to 9

When to Use / When Not to Use

Use WhenDon't Use WhenUse Instead
JavaScript/TypeScript projectsUsing Biome for both linting + formattingBiome (biomejs.dev)
Need granular rule controlDeno projects (built-in linter)deno lint + deno fmt
Team needs enforced code styleTiny scripts or one-off filesManual review

Important Caveats

Related Units