DEV Community

Muhammad Asif
Muhammad Asif

Posted on

Step-by-Step Guide to Setting Up Husky, ESLint, and Prettier in a Next.js TypeScript Project

1. Install Required Packages

First, ensure you have Node.js installed. Initialize your project using:

npm init -y
# OR
yarn init -y
Enter fullscreen mode Exit fullscreen mode

Next, install the necessary packages:

npm install --save-dev husky lint-staged eslint prettier eslint-config-prettier eslint-plugin-prettier eslint-plugin-unused-imports @typescript-eslint/parser @typescript-eslint/eslint-plugin
# OR
yarn add --dev husky lint-staged eslint prettier eslint-config-prettier eslint-plugin-prettier eslint-plugin-unused-imports @typescript-eslint/parser @typescript-eslint/eslint-plugin
Enter fullscreen mode Exit fullscreen mode

2. Setup husky

Use the husky init command to set up husky in your project:

npx husky init
Enter fullscreen mode Exit fullscreen mode

This command creates a pre-commit script in .husky/ and updates the prepare script in package.json. You can later modify these scripts as per your workflow.

3. Setup pre-commit

Create a pre-commit script in .husky/pre-commit:

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged
Enter fullscreen mode Exit fullscreen mode

4. Setup ESLint

Create an .eslintrc.json file in your project's root directory with ESLint configurations:

{
  "$schema": "https://json.schemastore.org/eslintrc.json",
  "env": {
    "browser": false,
    "es2021": true,
    "node": true
  },
  "extends": [
    "plugin:react/recommended",
    "plugin:prettier/recommended",
    "plugin:react-hooks/recommended",
    "plugin:jsx-a11y/recommended",
    "eslint:recommended",
    "plugin:prettier/recommended"
  ],
  "plugins": [
    "react",
    "unused-imports",
    "import",
    "@typescript-eslint",
    "jsx-a11y",
    "prettier"
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 12,
    "sourceType": "module"
  },
  "settings": {
    "react": {
      "version": "detect"
    }
  },
  "rules": {
    "no-console": "warn",
    "react/prop-types": "off",
    "react/jsx-uses-react": "off",
    "react/react-in-jsx-scope": "off",
    "react-hooks/exhaustive-deps": "off",
    "jsx-a11y/click-events-have-key-events": "warn",
    "jsx-a11y/interactive-supports-focus": "warn",
    "prettier/prettier": "warn",
    "no-unused-vars": "off",
    "unused-imports/no-unused-vars": "off",
    "unused-imports/no-unused-imports": "warn",
    "object-curly-spacing": [
      "error",
      "never"
    ],
    "@typescript-eslint/no-unused-vars": [
      "warn",
      {
        "args": "after-used",
        "ignoreRestSiblings": false,
        "argsIgnorePattern": "^_.*?$"
      }
    ],
    "import/order": [
      "warn",
      {
        "groups": [
          "type",
          "builtin",
          "object",
          "external",
          "internal",
          "parent",
          "sibling",
          "index"
        ],
        "pathGroups": [
          {
            "pattern": "~/**",
            "group": "external",
            "position": "after"
          }
        ],
        "newlines-between": "always"
      }
    ],
    "react/self-closing-comp": "warn",
    "react/jsx-sort-props": [
      "warn",
      {
        "callbacksLast": true,
        "shorthandFirst": true,
        "noSortAlphabetically": false,
        "reservedFirst": true
      }
    ],
    "padding-line-between-statements": [
      "warn",
      {
        "blankLine": "always",
        "prev": "*",
        "next": "return"
      },
      {
        "blankLine": "always",
        "prev": [
          "const",
          "let",
          "var"
        ],
        "next": "*"
      },
      {
        "blankLine": "any",
        "prev": [
          "const",
          "let",
          "var"
        ],
        "next": [
          "const",
          "let",
          "var"
        ]
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

5. Setup ESLint Ignore

Create an .eslintignore file to ignore specific files from ESLint:

.next/*
*.css
dist
esm/*
public/*
tests/*
scripts/*
*.config.js
node_modules
coverage
.next
build
Enter fullscreen mode Exit fullscreen mode

6. Setup Prettier

Create a .prettierrc.json file with Prettier configurations:

{
  "$schema": "https://json.schemastore.org/prettierrc.json",
  "tabWidth": 2,
  "printWidth": 100,
  "semi": true,
  "useTabs": false,
  "singleQuote": false,
  "bracketSpacing": false,
  "endOfLine": "auto",
  "arrowParens": "always",
  "trailingComma": "all"
}
Enter fullscreen mode Exit fullscreen mode

7. Setup Prettier Ignore

Create a .prettierignore file to ignore specific files from Prettier:

dist
node_modules
.next
build
scripts
Enter fullscreen mode Exit fullscreen mode

8. Configure Husky and lint-staged

Update your package.json with Husky and lint-staged configurations:

"husky": {
  "hooks": {
    "pre-commit": "lint-staged"
  }
},
"lint-staged": {
  "*.{js,jsx,ts,tsx,json,css,scss,md}": [
    "eslint --fix",
    "prettier --write"
  ]
}
Enter fullscreen mode Exit fullscreen mode

9. Add Scripts

Optionally, add scripts to your package.json for easier usage:

"scripts": {
  "eslint": "eslint . --ext .js,.jsx,.ts,.tsx",
  "format": "prettier --write ."
}
Enter fullscreen mode Exit fullscreen mode

Now, you can run npm run eslint to check for linting errors and npm run format to format your code with Prettier. Before committing your code, Husky will automatically run lint-staged, fixing linting errors and formatting your code.

Top comments (1)

Collapse
 
shivanandan17 profile image
Shivanandan D N

Good read. Additional info, use npm run eslint -- --fix for auto fixing lint warns.