# eslint-config-prettier ## Introduction eslint-config-prettier is an ESLint configuration package that turns off all ESLint rules that are unnecessary or might conflict with Prettier. This allows developers to use their favorite shareable ESLint config alongside Prettier without worrying about stylistic rule conflicts. The package supports both the traditional eslintrc configuration format and the newer flat config format introduced in ESLint 8+. The package works by providing a configuration object that sets conflicting rules to "off", ensuring that Prettier handles all code formatting while ESLint focuses on code quality rules. It automatically handles rules from ESLint core and popular plugins including @typescript-eslint, React, Vue, Babel, Flowtype, Unicorn, and @stylistic. Additionally, it includes a CLI helper tool that analyzes your ESLint configuration files to detect and report any rules that might conflict with Prettier. ## Installation and Configuration ### Installing the Package ```bash npm i -D eslint-config-prettier ``` ```bash yarn add -D eslint-config-prettier ``` ```bash pnpm add -D eslint-config-prettier ``` ### ESLintRC Configuration (Legacy Format) ```json { "extends": [ "some-other-config-you-use", "prettier" ] } ``` ### Flat Config Configuration (ESLint 8.21+) ```javascript import someConfig from "some-other-config-you-use"; import eslintConfigPrettier from "eslint-config-prettier/flat"; export default [ someConfig, eslintConfigPrettier, ]; ``` ## CLI Helper Tool ### Check Configuration for Conflicts ```bash npx eslint-config-prettier path/to/main.js ``` ```bash # Check multiple files with different configs npx eslint-config-prettier index.js test/index.js legacy/main.js ``` **Expected Output (No Conflicts):** ``` No rules that are unnecessary or conflict with Prettier were found. ``` **Expected Output (Conflicts Found):** ``` The following rules are unnecessary or might conflict with Prettier: - indent - quotes ``` **Exit Codes:** - 0: No problems found - 1: Unexpected error - 2: Conflicting rules found ### Using with Environment Variables ```bash # Force flat config ESLINT_USE_FLAT_CONFIG=true npx eslint-config-prettier index.js ``` ```bash # Force eslintrc ESLINT_USE_FLAT_CONFIG=false npx eslint-config-prettier index.js ``` ```bash # Exclude deprecated rules from CLI output ESLINT_CONFIG_PRETTIER_NO_DEPRECATED=true npx eslint-config-prettier index.js ``` ## Programmatic API ### Using the Rules Object (CommonJS) ```javascript const eslintConfigPrettier = require("eslint-config-prettier"); // Access all rules that are turned off console.log(eslintConfigPrettier.rules); // Example output structure: // { // "curly": 0, // "no-unexpected-multiline": 0, // "@stylistic/indent": "off", // "@typescript-eslint/indent": "off", // "array-bracket-spacing": "off", // // ... hundreds more rules // } ``` ### Using the Flat Config Export ```javascript const flatConfig = require("eslint-config-prettier/flat"); console.log(flatConfig.name); // "config-prettier" console.log(flatConfig.rules); // Same rules object as above ``` ### Using the Prettier-Specific Rules ```javascript const prettierRules = require("eslint-config-prettier/prettier"); // Rules that conflict specifically with eslint-plugin-prettier console.log(prettierRules.rules); // { // "arrow-body-style": 0, // "prefer-arrow-callback": 0 // } ``` ## Special Rules Configuration ### Curly Rule with Prettier ```json { "extends": ["prettier"], "rules": { "curly": ["error", "all"] } } ``` ### Lines Around Comment Rule ```json { "extends": ["prettier"], "rules": { "lines-around-comment": [ "error", { "beforeBlockComment": true, "afterBlockComment": true, "beforeLineComment": true, "afterLineComment": true, "allowBlockStart": true, "allowBlockEnd": true, "allowObjectStart": true, "allowObjectEnd": true, "allowArrayStart": true, "allowArrayEnd": true } ] } } ``` ### Max Length Rule ```json { "extends": ["prettier"], "rules": { "max-len": ["error", {"code": 80, "ignoreUrls": true}] } } ``` **Prettier Configuration (.prettierrc):** ```json { "printWidth": 80 } ``` ### No Confusing Arrow Rule ```json { "extends": ["prettier"], "rules": { "no-confusing-arrow": ["error", {"allowParens": false}] } } ``` ### No Tabs Rule with Indentation ```json { "extends": ["prettier"], "rules": { "no-tabs": ["error", {"allowIndentationTabs": true}] } } ``` ### Quotes Rule - Enforce Backticks ```json { "extends": ["prettier"], "rules": { "quotes": ["error", "backtick"] } } ``` ### Quotes Rule - Forbid Unnecessary Backticks (Double Quotes) ```json { "extends": ["prettier"], "rules": { "quotes": [ "error", "double", {"avoidEscape": true, "allowTemplateLiterals": false} ] } } ``` **Prettier Configuration:** ```json { "singleQuote": false } ``` ### Quotes Rule - Forbid Unnecessary Backticks (Single Quotes) ```json { "extends": ["prettier"], "rules": { "quotes": [ "error", "single", {"avoidEscape": true, "allowTemplateLiterals": false} ] } } ``` **Prettier Configuration:** ```json { "singleQuote": true } ``` ### Vue HTML Self-Closing Rule ```json { "extends": ["prettier"], "rules": { "vue/html-self-closing": [ "error", { "html": { "void": "any" } } ] } } ``` ### Unicorn Template Indent Rule ```json { "extends": ["prettier"], "rules": { "unicorn/template-indent": [ "error", { "tags": ["outdent", "dedent", "sql", "styled"], "functions": ["dedent", "stripIndent"], "selectors": [], "comments": ["indent"] } ] } } ``` ### No Sequences Rule with Restricted Syntax ```json { "extends": ["prettier"], "rules": { "no-restricted-syntax": [ "error", { "selector": "SequenceExpression", "message": "The comma operator is confusing and a common mistake. Don't use it!" } ] } } ``` ## TypeScript Configuration ### TypeScript with Flat Config ```javascript import typescriptEslint from "@typescript-eslint/eslint-plugin"; import eslintConfigPrettier from "eslint-config-prettier/flat"; export default [ { plugins: { "@typescript-eslint": typescriptEslint, }, rules: { "@typescript-eslint/semi": "off", }, }, eslintConfigPrettier, ]; ``` ### TypeScript with ESLintRC ```json { "extends": [ "plugin:@typescript-eslint/recommended", "prettier" ], "parser": "@typescript-eslint/parser", "plugins": ["@typescript-eslint"] } ``` ## React Configuration ### React with Flat Config ```javascript import reactPlugin from "eslint-plugin-react"; import eslintConfigPrettier from "eslint-config-prettier/flat"; export default [ { plugins: { react: reactPlugin, }, rules: reactPlugin.configs.recommended.rules, }, eslintConfigPrettier, ]; ``` ### React with ESLintRC ```json { "extends": [ "react-app", "prettier" ] } ``` ## Vue Configuration ### Vue with Flat Config ```javascript import vuePlugin from "eslint-plugin-vue"; import eslintConfigPrettier from "eslint-config-prettier/flat"; export default [ ...vuePlugin.configs["flat/recommended"], eslintConfigPrettier, ]; ``` ### Vue with ESLintRC ```json { "extends": [ "plugin:vue/vue3-recommended", "prettier" ] } ``` ## CLI Helper Tool Programmatic Usage ### Processing Rules Programmatically ```javascript const { processRules } = require("eslint-config-prettier/bin/cli.js"); // Example: Check specific rules const configRules = [ ["indent", ["error", 2], "index.js"], ["quotes", ["error", "double"], "index.js"], ["semi", ["error", "always"], "index.js"], ]; const result = processRules(configRules); console.log(result); // { // stdout: "The following rules are unnecessary or might conflict with Prettier:\n\n- indent\n- quotes\n- semi", // code: 2 // } if (result.code === 0) { console.log("✓ No conflicts found"); } else if (result.code === 2) { console.error("✗ Conflicts detected"); console.error(result.stdout); } ``` ## Integration with CI/CD ### GitHub Actions Workflow ```yaml name: Lint on: [push, pull_request] jobs: eslint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 18 - run: npm ci - run: npx eslint-config-prettier src/index.js - run: npm run lint ``` ### NPM Script Integration ```json { "scripts": { "lint": "eslint .", "lint:check-prettier": "eslint-config-prettier index.js", "pretest": "npm run lint:check-prettier && npm run lint" } } ``` ### Pre-commit Hook with Husky ```bash #!/bin/sh . "$(dirname "$0")/_/husky.sh" npx eslint-config-prettier src/index.js || exit 1 npx eslint . || exit 1 ``` ## Summary eslint-config-prettier serves as an essential bridge between ESLint and Prettier, eliminating configuration conflicts and allowing both tools to work together harmoniously. The main use cases include setting up new projects with both ESLint and Prettier, migrating existing ESLint configurations to work with Prettier, and maintaining consistent code quality and formatting across teams. The CLI helper tool is particularly valuable for continuous integration pipelines and pre-commit hooks, ensuring that conflicting rules are caught early in the development process. The package integrates seamlessly with modern JavaScript frameworks and tools including React, Vue, TypeScript, and various ESLint plugins. By using eslint-config-prettier, development teams can leverage Prettier's superior formatting capabilities while maintaining ESLint's powerful static analysis and code quality checks. The special rules system provides flexibility for advanced use cases where certain ESLint rules can coexist with Prettier when properly configured, giving teams fine-grained control over their code standards without sacrificing the benefits of automated formatting.