Pre-commit Hooks and Commit Message Validation in Next.js & React Projects

Filippo CaliòFilippo Caliò
3 min read

Pre-commit Hooks with Husky

Installation & Setup

First, install Husky and enable it in your project:

npm install --save-dev husky
npx husky install

Also, make sure you add this to your package.json:

"scripts": {
  "prepare": "husky install"
}

Configuration

Create a .husky/pre-commit file with the following content:


npm run lint && npm run type-check && npm run build

Then make it executable:

chmod +x .husky/pre-commit

What Happens

From now on, every time you try to commit:

  • npm run lint runs your linter
  • npm run type-check validates your TypeScript types
  • npm run build makes sure the project still compiles

If one of these fails, the commit won’t go through.


Commit Message Validation with commitlint

Installation

Install commitlint with the conventional commit rules:

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

Configuration

Create a commitlint.config.js file:

module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [
      2,
      'always',
      [
        'feat',
        'fix',
        'docs',
        'style',
        'refactor',
        'test',
        'chore',
        'build',
        'ci'
      ]
    ],
    'header-max-length': [2, 'always', 72]
  }
};

Setup Git Hook

Add a commit message hook with Husky:

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

Commit Message Format

Structure

A commit message should follow this format:

type: description

Allowed Types

TypeDescription
featNew feature
fixBug fix
docsDocumentation updates
styleCode style / formatting
refactorCode refactoring
testAdding or updating tests
choreMaintenance, dependencies
buildBuild system changes
ciCI/CD or deployment changes

Correct Examples

feat: add file upload component
fix: resolve memory leak in processing
docs: update README with installation steps
style: fix eslint warnings in auth module
refactor: extract upload logic to separate service
test: add unit tests for file validation
chore: upgrade Next.js to v15
build: update webpack configuration
ci: add deployment pipeline

Incorrect Examples

"Fix bug"                       # Missing type
"FEAT: add feature"             # Type must be lowercase
"feat: Add new feature."        # No period at the end
"feat:"                         # Empty description
"feat: Add very long commit..." # Too long
"update: change something"      # Invalid type

Package.json Scripts

Add these scripts to your package.json:

"scripts": {
  "prepare": "husky install",
  "commitlint": "commitlint --edit"
}

Benefits

  • Code Quality: linting and type checking happen automatically
  • Build Safety: the build can’t be broken silently
  • Consistency: commit messages follow a common format
  • Team Collaboration: commit history is easier to read and maintain
  • Automation: no need to remember all these checks manually

Troubleshooting

If your commits fail:

  1. Make sure all hooks are executable (chmod +x .husky/*)
  2. Double-check the commitlint.config.js syntax
  3. Verify your commit message format
  4. Confirm that the required npm scripts exist in package.json

Pro Tip:
If you really need to bypass the hooks (e.g. in an emergency), you can use:

git commit --no-verify

But keep this as an exception, not the rule.

1
Subscribe to my newsletter

Read articles from Filippo Caliò directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Filippo Caliò
Filippo Caliò