Skip to content

Instantly share code, notes, and snippets.

@XronTrix10
Last active December 18, 2024 18:43
Show Gist options
  • Save XronTrix10/587a2b28953ea262799258139859af16 to your computer and use it in GitHub Desktop.
Save XronTrix10/587a2b28953ea262799258139859af16 to your computer and use it in GitHub Desktop.
Set up ESlint and Prettier for Next.js with Typescript and TailwindCSS

Set up ESlint and Prettier for Next.js 14 with Typescript and TailwindCSS

Create Next App with starter template ( Last Version of Next 14 )

npx [email protected] --ts --tailwind --app --src-dir --use-yarn --eslint

Install Dev Dependencies

For npm

npm install --save-dev prettier eslint-plugin-react eslint-config-prettier eslint-plugin-prettier prettier-plugin-tailwindcss @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-next eslint-plugin-jsdoc eslint-plugin-tailwindcss husky

for Yarn

yarn add --dev prettier eslint-plugin-react eslint-config-prettier eslint-plugin-prettier prettier-plugin-tailwindcss @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-next eslint-plugin-jsdoc eslint-plugin-tailwindcss husky

Configure ESLint

Create .eslintrc.json at the root folder and paste the below inside

{
  "root": true,
  "env": {
    "browser": true,
    "es6": true,
    "node": true
  },
  "settings": {
    "react": {
      "version": "detect"
    }
  },
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "project": "./tsconfig.json",
    "ecmaVersion": 2024,
    "ecmaFeatures": {
      "jsx": true,
      "arrowFunctions": true
    },
    "sourceType": "module"
  },
  "ignorePatterns": ["node_modules", "build", "dist", "public"],
  "extends": [
    "next",
    "next/core-web-vitals",
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:jsdoc/recommended",
    "plugin:tailwindcss/recommended",
    "plugin:@typescript-eslint/recommended",
    "prettier"
  ],
  "plugins": ["react", "jsdoc", "tailwindcss", "@typescript-eslint"],
  "rules": {
    // Disallow the use of variables that are defined but never used
    "no-unused-vars": "warn",
    // Prefer using === and !== over == and !=
    "eqeqeq": ["warn", "always"],
    // Prefer using const and let over var
    "no-var": "error",

    // Prefer using arrow functions for callbacks
    "prefer-arrow-callback": ["warn", { "allowNamedFunctions": false }],
    // Prefer using function expressions instead of function declarations
    "func-style": ["warn", "expression", { "allowArrowFunctions": true }],

    // React specific rules
    "react/prop-types": "off",
    "react/react-in-jsx-scope": "off",
    "react/no-array-index-key": "error",
    "react/self-closing-comp": "warn",
    "react/no-unescaped-entities": "error",
    "react/jsx-no-target-blank": "error",
    "react/jsx-no-useless-fragment": ["warn", { "allowExpressions": true }],
    "react/sort-comp": "error",

    // React hooks specific rules
    "react-hooks/exhaustive-deps": "warn",
    "react-hooks/rules-of-hooks": "error",

    // Next.js specific rules
    "@next/no-img-element": "off",

    // TypeScript specific rules
    "@typescript-eslint/explicit-function-return-type": "warn",
    "@typescript-eslint/consistent-type-imports": "error",
    "@typescript-eslint/consistent-type-exports": "error",
    "@typescript-eslint/consistent-type-definitions": ["error", "type"],

    // Imports specific rules
    "sort-imports": [
      "error",
      {
        "ignoreCase": true,
        "ignoreDeclarationSort": true,
        "ignoreMemberSort": false
      }
    ],
    "import/order": [
      "error",
      {
        "groups": ["builtin", "external", "internal"],
        "pathGroups": [
          {
            "pattern": "react",
            "group": "external",
            "position": "before"
          }
        ],
        "newlines-between": "always"
      }
    ],

    // JSDoc specific rules for Open Source projects
    "jsdoc/require-jsdoc": [
      "error",
      {
        "require": {
          "ArrowFunctionExpression": true,
          "ClassDeclaration": true,
          "FunctionDeclaration": true,
          "FunctionExpression": true,
          "MethodDefinition": true
        }
      }
    ],
    "jsdoc/require-param": "error",
    "jsdoc/require-param-type": "error",
    "jsdoc/require-returns": "error",
    "jsdoc/require-returns-type": "error",
    "jsdoc/require-property": "error",
    "jsdoc/require-property-description": "error",
    "jsdoc/require-property-type": "error"
  }
}

Configure Prettier

Create .prettierrc at the root folder and paste the below inside

{
    "trailingComma": "all",
    "tabWidth": 2,
    "useTabs": false,
    "semi": true,
    "singleQuote": false
}

Create .prettierignore at the root folder and paste the below inside

# Ignore artifacts:
.cache
.next
package.json
package-lock.json
public

Setup Husky

npx husky init

Paste the below inside .husky/pre-commit

# .husky/pre-commit
echo "Running husky pre-commit hook"
eslint --fix
prettier $(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g') --write --ignore-unknown
git update-index --again
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment