Next.js starter your AI actually understands. Ship internal tools in days not weeks. Pre-order $199 $499 → [Get it now]

How to set up Husky with Vue

Git hooks are essential for maintaining code quality in Vue projects, but setting them up manually is error-prone and inconsistent across team members. With over 10 years of experience building Vue applications and as the creator of CoreUI, I’ve set up automated Git hooks in hundreds of projects to enforce linting, testing, and formatting standards. From my expertise, the most reliable approach is to use Husky, a tool that makes Git hooks easy to configure and share across your team. This method ensures consistent code quality checks before every commit and push.

Install Husky using npm and initialize it to automatically manage Git hooks in your Vue project.

npm install --save-dev husky
npx husky init

How It Works

The husky init command creates a .husky directory in your project with a pre-commit hook example. Git will automatically execute these hook scripts before commits, allowing you to run linters, tests, or formatters. The hooks are committed to version control, ensuring all team members use the same quality checks.

Setting Up Pre-Commit Hook

Configure a pre-commit hook to run ESLint before each commit:

echo "npm run lint" > .husky/pre-commit
chmod +x .husky/pre-commit

Add the lint script to your package.json:

{
  "scripts": {
    "lint": "eslint --ext .js,.vue src",
    "lint:fix": "eslint --ext .js,.vue src --fix"
  }
}

This pre-commit hook runs ESLint on all JavaScript and Vue files in the src directory before allowing the commit. If linting fails, the commit is blocked, preventing broken code from entering the repository. The --ext flag tells ESLint which file extensions to check.

Adding Prettier Formatting

Combine Husky with lint-staged to format only changed files:

npm install --save-dev lint-staged

Update package.json:

{
  "scripts": {
    "lint": "eslint --ext .js,.vue src",
    "format": "prettier --write src/**/*.{js,vue}"
  },
  "lint-staged": {
    "*.{js,vue}": [
      "eslint --fix",
      "prettier --write"
    ]
  }
}

Update the pre-commit hook:

echo "npx lint-staged" > .husky/pre-commit

Now lint-staged only runs ESLint and Prettier on files that are staged for commit, making the process much faster. The formatters automatically fix issues and write the changes back to the files before the commit completes.

Setting Up Pre-Push Hook

Add a pre-push hook to run tests before pushing to remote:

echo "npm run test:unit" > .husky/pre-push
chmod +x .husky/pre-push

Add the test script to package.json:

{
  "scripts": {
    "test:unit": "vitest run"
  }
}

The pre-push hook runs unit tests before allowing a push to the remote repository. This catches failing tests before they reach CI/CD, saving time and preventing broken builds from being shared with the team.

Configuring Commit Message Format

Enforce conventional commit messages using commitlint:

npm install --save-dev @commitlint/cli @commitlint/config-conventional

Create commitlint.config.js:

export default {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [
      2,
      'always',
      ['feat', 'fix', 'docs', 'style', 'refactor', 'test', 'chore']
    ]
  }
}

Add commit-msg hook:

echo "npx commitlint --edit \$1" > .husky/commit-msg
chmod +x .husky/commit-msg

This configuration enforces commit messages like feat: add user authentication or fix: resolve navigation bug. The hook validates the commit message format before allowing the commit, ensuring consistent Git history across the project.

Running Type Checks

For Vue 3 with TypeScript, add type checking to the pre-commit hook:

npm install --save-dev vue-tsc

Update package.json:

{
  "scripts": {
    "type-check": "vue-tsc --noEmit"
  }
}

Update the pre-commit hook to include type checking:

echo "npm run type-check && npx lint-staged" > .husky/pre-commit

The vue-tsc command runs TypeScript type checking without emitting files. The --noEmit flag makes it fast since it only checks types without generating JavaScript output. This catches type errors before they reach the repository.

Skipping Hooks When Needed

Bypass hooks in emergency situations using the --no-verify flag:

git commit -m "fix: critical hotfix" --no-verify

This skips all pre-commit hooks, allowing you to commit without running linters or tests. Use this sparingly and only in emergencies, as it bypasses all quality checks. Always follow up by fixing any issues that would have been caught by the hooks.

Best Practice Note

This is the same Git hooks setup we use in CoreUI Vue projects to maintain consistent code quality across our team. Husky ensures every contributor follows the same standards without manual configuration. For best results, combine Husky with ESLint, Prettier, and a testing framework to create a comprehensive quality gate. Document your hook setup in the project README so new team members understand the workflow. If you’re new to Vue, start with how to create a new Vue 3 project before setting up Husky. Consider using CoreUI Vue components which come with pre-configured linting and formatting rules that work seamlessly with Husky.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author