PHPackages                             dev-kraken/php-commitlint - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Validation &amp; Sanitization](/categories/validation)
4. /
5. dev-kraken/php-commitlint

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

dev-kraken/php-commitlint
=========================

A powerful Git hooks and commit message linting tool for PHP projects - combining the best of husky and commitlint in a native PHP implementation

v1.2.0(11mo ago)119↓50%MITPHPPHP ^8.3CI passing

Since Jun 20Pushed 11mo agoCompare

[ Source](https://github.com/dev-kraken/php-commitlint)[ Packagist](https://packagist.org/packages/dev-kraken/php-commitlint)[ Docs](https://github.com/dev-kraken/php-commitlint)[ GitHub Sponsors](https://github.com/sponsors/dev-kraken)[ RSS](/packages/dev-kraken-php-commitlint/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (7)Versions (4)Used By (0)

[   ![PHP CommitLint Banner](banner/banner_light.png) ](https://devkraken.com/)PHP CommitLint 🎯
================

[](#php-commitlint-)

A powerful Git hooks and commit message linting tool for PHP projects - combining the best of husky and commitlint in a native PHP implementation.

[![PHP Version](https://camo.githubusercontent.com/ef0054230522e542bc1f908ac005c6c75888dea255bac910f9015e12095e31d7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253545382e332d626c7565)](https://www.php.net/)[![License](https://camo.githubusercontent.com/f8df3091bbe1149f398a5369b2c39e896766f9f6efba3477c63e9b4aa940ef14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e)](LICENSE)[![CI](https://github.com/devkraken/php-commitlint/workflows/CI/badge.svg)](https://github.com/devkraken/php-commitlint/actions)[![Tests](https://camo.githubusercontent.com/af9c819671bf51e20ffda2a2ea34badb3bc462df66b92974d9c6e5c6ddb0e139/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74657374732d706573742d677265656e)](https://pestphp.com/)

🚀 Features
----------

[](#-features)

- **🎯 Commit Message Validation** - Enforce conventional commit format with customizable rules
- **🪝 Git Hooks Management** - Easy installation and management of Git hooks
- **⚙️ Flexible Configuration** - Configure via `.commitlintrc.json` or `composer.json`
- **🔧 Developer Friendly** - Beautiful CLI output with helpful error messages
- **📦 Zero Dependencies** - Pure PHP implementation using only Symfony Console
- **🧪 Fully Tested** - Comprehensive test suite with Pest
- **🎨 Modern PHP** - PHP 8.3+ with strict types and modern syntax
- **🔒 Security First** - Built-in security features and input validation
- **🎛️ Custom Hooks** - Add your own git hooks with custom commands

📦 Installation
--------------

[](#-installation)

Install via Composer:

```
composer require --dev dev-kraken/php-commitlint
```

🔧 Quick Start
-------------

[](#-quick-start)

### 1. Install Git Hooks

[](#1-install-git-hooks)

```
vendor/bin/php-commitlint install
```

### 2. Start Making Commits!

[](#2-start-making-commits)

```
# ✅ Valid commits
git commit -m "feat: add user authentication"
git commit -m "fix(auth): resolve login validation issue"
git commit -m "docs: update README with examples"

# ❌ Invalid commits (will be rejected)
git commit -m "added new feature"  # Missing type
git commit -m "FIX: something"     # Invalid type case
```

📋 Commands
----------

[](#-commands)

### Install Hooks

[](#install-hooks)

Install Git hooks and create default configuration:

```
vendor/bin/php-commitlint install [options]
```

**Options:**

- `--force, -f` - Force installation even if hooks already exist
- `--skip-config` - Skip creating default configuration file

### Validate Commit Message

[](#validate-commit-message)

Validate commit messages against your configuration:

```
# Validate current commit message (from .git/COMMIT_EDITMSG)
vendor/bin/php-commitlint validate

# Validate specific message
vendor/bin/php-commitlint validate "feat: add new feature"

# Validate from file
vendor/bin/php-commitlint validate --file=commit.txt

# Quiet mode (exit code only)
vendor/bin/php-commitlint validate --quiet

# Verbose error details
vendor/bin/php-commitlint validate --verbose-errors
```

**Options:**

- `--file, -f` - Read commit message from specific file
- `--quiet, -q` - Suppress output (exit code only)
- `--verbose-errors` - Show detailed error information

### Manage Custom Hooks

[](#manage-custom-hooks)

Add and manage custom Git hooks:

```
# Add custom hook
vendor/bin/php-commitlint add pre-commit "vendor/bin/pest"
vendor/bin/php-commitlint add pre-push "vendor/bin/phpstan analyse"

# Remove hook
vendor/bin/php-commitlint remove pre-commit [--force]

# List all hooks and configuration
vendor/bin/php-commitlint status

# Show detailed information
vendor/bin/php-commitlint status --verbose

# Show only hooks or config
vendor/bin/php-commitlint status --hooks-only
vendor/bin/php-commitlint status --config-only
```

### Uninstall

[](#uninstall)

Remove all installed Git hooks:

```
vendor/bin/php-commitlint uninstall [--force]
```

⚙️ Configuration
----------------

[](#️-configuration)

PHP CommitLint can be configured via `.commitlintrc.json` file or within your `composer.json`. The tool automatically merges your custom configuration with sensible defaults.

### Configuration File Priority

[](#configuration-file-priority)

1. `.commitlintrc.json` in your project root
2. `extra.php-commitlint` in `composer.json`
3. Default configuration

### Complete Configuration Reference

[](#complete-configuration-reference)

```
{
  "auto_install": false,
  "rules": {
    "type": {
      "required": true,
      "allowed": ["feat", "fix", "docs", "style", "refactor", "perf", "test", "chore", "ci", "build", "revert"]
    },
    "scope": {
      "required": false,
      "allowed": []
    },
    "subject": {
      "min_length": 1,
      "max_length": 100,
      "case": "any",
      "end_with_period": false
    },
    "body": {
      "max_line_length": 100,
      "leading_blank": true
    },
    "footer": {
      "leading_blank": true
    }
  },
  "patterns": {
    "breaking_change": "/^BREAKING CHANGE:/",
    "issue_reference": "/(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\\s+#\\d+/i"
  },
  "hooks": {
    "commit-msg": true,
    "pre-commit": false,
    "pre-push": false
  },
  "pre_commit_commands": {
    "Code Style Check": "vendor/bin/php-cs-fixer fix --dry-run --diff",
    "Static Analysis": "vendor/bin/phpstan analyse --no-progress",
    "Unit Tests": "vendor/bin/pest --filter=Unit",
    "Security Check": "composer audit"
  },
  "format": {
    "type": true,
    "scope": "optional",
    "description": true,
    "body": "optional",
    "footer": "optional"
  }
}
```

### Configuration Options Explained

[](#configuration-options-explained)

#### General Settings

[](#general-settings)

- **`auto_install`** (`boolean`, default: `false`) - Automatically install hooks when composer install/update runs

#### Rules Configuration

[](#rules-configuration)

##### Type Rules (`rules.type`)

[](#type-rules-rulestype)

- **`required`** (`boolean`, default: `true`) - Whether commit type is required
- **`allowed`** (`array`, default: see above) - Array of allowed commit types

##### Scope Rules (`rules.scope`)

[](#scope-rules-rulesscope)

- **`required`** (`boolean`, default: `false`) - Whether commit scope is required
- **`allowed`** (`array`, default: `[]`) - Array of allowed scopes (empty = any scope allowed)

##### Subject Rules (`rules.subject`)

[](#subject-rules-rulessubject)

- **`min_length`** (`int`, default: `1`) - Minimum subject length
- **`max_length`** (`int`, default: `100`) - Maximum subject length
- **`case`** (`string`, default: `"any"`) - Case requirement: `"lower"`, `"upper"`, or `"any"`
- **`end_with_period`** (`boolean`, default: `false`) - Whether subject must end with period

##### Body Rules (`rules.body`)

[](#body-rules-rulesbody)

- **`max_line_length`** (`int`, default: `100`) - Maximum line length for body (0 = no limit)
- **`leading_blank`** (`boolean`, default: `true`) - Require blank line between subject and body

##### Footer Rules (`rules.footer`)

[](#footer-rules-rulesfooter)

- **`leading_blank`** (`boolean`, default: `true`) - Require blank line between body and footer

#### Pattern Validation (`patterns`)

[](#pattern-validation-patterns)

Define custom regex patterns for additional validation:

```
{
  "patterns": {
    "breaking_change": "/^BREAKING CHANGE:/",
    "issue_reference": "/(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\\s+#\\d+/i",
    "ticket_reference": "/JIRA-\\d+/"
  }
}
```

#### Hook Configuration (`hooks`)

[](#hook-configuration-hooks)

Control which Git hooks are installed:

```
{
  "hooks": {
    "commit-msg": true,    // Validate commit messages
    "pre-commit": false,   // Run before commits
    "pre-push": false      // Run before pushes
  }
}
```

#### Team-Wide Pre-Commit Commands (`pre_commit_commands`)

[](#team-wide-pre-commit-commands-pre_commit_commands)

Configure commands that run automatically for all team members during pre-commit:

```
{
  "hooks": {
    "pre-commit": true
  },
  "pre_commit_commands": {
    "Code Style Check": "vendor/bin/php-cs-fixer fix --dry-run --diff",
    "Static Analysis": "vendor/bin/phpstan analyse --no-progress",
    "Unit Tests": "vendor/bin/pest --filter=Unit",
    "Security Check": "composer audit"
  }
}
```

**Benefits:**

- **Automatic for all team members** - No manual hook setup required
- **Consistent quality checks** - Same commands run for everyone
- **Version controlled** - Configuration is committed and shared
- **Easy maintenance** - Update once, applies to all developers

When any team member runs `composer install` (with `auto_install: true`), these commands automatically run before every commit.

#### Format Configuration (`format`)

[](#format-configuration-format)

- **`type`** (`boolean`) - Require commit type
- **`scope`** (`string`) - Scope requirement: "required", "optional", "forbidden"
- **`description`** (`boolean`) - Require commit description
- **`body`** (`string`) - Body requirement: "required", "optional", "forbidden"
- **`footer`** (`string`) - Footer requirement: "required", "optional", "forbidden"

🪟 Windows Support
-----------------

[](#-windows-support)

PHP CommitLint provides full Windows compatibility with automatic detection and setup:

### **Automatic Windows Support**

[](#automatic-windows-support)

- **PHP Detection**: Automatically finds PHP in XAMPP, WAMP, Laragon, or standard installations
- **Path Handling**: Converts Windows paths for Git Bash compatibility
- **Batch Wrapper**: Includes `php-commitlint.bat` for Windows CLI
- **Hook Compatibility**: Git hooks work seamlessly in Git Bash, PowerShell, and Command Prompt

### **Windows Installation**

[](#windows-installation)

```
# Works in PowerShell, Command Prompt, or Git Bash
composer require --dev dev-kraken/php-commitlint
vendor\bin\php-commitlint install  # Windows
# OR
vendor/bin/php-commitlint install   # Git Bash
```

### **Windows Troubleshooting**

[](#windows-troubleshooting)

**If you see "PHP CommitLint not found":**

1. Ensure PHP is in your PATH: `php --version`
2. Try using the batch file: `vendor\bin\php-commitlint.bat install`
3. Check Git Bash compatibility: Use `/c/path/to/php` format

**Common Windows Scenarios:**

- **XAMPP**: `C:\xampp\php\php.exe` (automatically detected)
- **WAMP**: `C:\wamp\bin\php\php8.3\php.exe` (automatically detected)
- **Laragon**: `C:\laragon\bin\php\php8.3\php.exe` (automatically detected)
- **Standalone**: `C:\php\php.exe` (automatically detected)

📖 Example Configurations
------------------------

[](#-example-configurations)

#### Minimal Configuration (`examples/commitlintrc.minimal.json`)

[](#minimal-configuration-examplescommitlintrcminimaljson)

```
{
  "rules": {
    "type": {
      "allowed": ["feat", "fix", "docs", "chore"]
    },
    "subject": {
      "max_length": 50
    }
  }
}
```

#### Strict Configuration (`examples/commitlintrc.strict.json`)

[](#strict-configuration-examplescommitlintrcstrictjson)

```
{
  "auto_install": true,
  "rules": {
    "type": {
      "required": true,
      "allowed": ["feat", "fix", "docs", "test", "refactor", "chore"]
    },
    "scope": {
      "required": true,
      "allowed": ["auth", "api", "ui", "db", "config", "test", "docs"]
    },
    "subject": {
      "min_length": 10,
      "max_length": 50,
      "case": "lower",
      "end_with_period": false
    },
    "body": {
      "max_line_length": 72,
      "leading_blank": true
    },
    "footer": {
      "leading_blank": true
    }
  },
  "patterns": {
    "breaking_change": "/^BREAKING CHANGE:/",
    "issue_reference": "/(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\\s+#\\d+/i",
    "ticket_reference": "/JIRA-\\d+/"
  },
  "hooks": {
    "commit-msg": true,
    "pre-commit": true,
    "pre-push": false
  }
}
```

### Configuration in `composer.json`

[](#configuration-in-composerjson)

You can also configure PHP CommitLint in your `composer.json`:

```
{
  "extra": {
    "php-commitlint": {
      "auto_install": true,
      "rules": {
        "type": {
          "allowed": ["feat", "fix", "docs", "test", "chore"]
        },
        "subject": {
          "max_length": 80
        }
      }
    }
  }
}
```

📝 Commit Message Format
-----------------------

[](#-commit-message-format)

This package enforces the [Conventional Commits](https://conventionalcommits.org/) specification:

```
[optional scope]:

[optional body]

[optional footer(s)]

```

### Examples

[](#examples)

```
# Simple commit
feat: add user registration

# With scope
feat(auth): add JWT token validation

# With body and footer
feat(api): add user endpoints

Add comprehensive user management endpoints including:
- GET /api/users
- POST /api/users
- PUT /api/users/{id}
- DELETE /api/users/{id}

Closes #123

# Breaking change
feat(api)!: redesign user authentication

BREAKING CHANGE: The authentication API has been completely redesigned.
All existing tokens will be invalidated.

# Multiple footers
fix(auth): resolve token validation issue

The token validation was failing for users with special characters
in their usernames.

Fixes #456
Reviewed-by: @johndoe
```

### Default Commit Types

[](#default-commit-types)

- **`feat`** - New features
- **`fix`** - Bug fixes
- **`docs`** - Documentation changes
- **`style`** - Code style changes (formatting, etc)
- **`refactor`** - Code refactoring
- **`perf`** - Performance improvements
- **`test`** - Adding or updating tests
- **`chore`** - Maintenance tasks
- **`ci`** - CI/CD changes
- **`build`** - Build system changes
- **`revert`** - Reverting previous commits

### Special Commit Types (Auto-Skip Validation)

[](#special-commit-types-auto-skip-validation)

The following commit types automatically skip validation:

- **Merge commits** - `Merge branch "feature" into main`
- **Revert commits** - `Revert "feat: add user authentication"`
- **Initial commits** - `Initial commit`
- **Fixup commits** - `fixup! feat: add user authentication`

🛠️ Development &amp; Testing
----------------------------

[](#️-development--testing)

### Running Tests

[](#running-tests)

```
# Run all tests
composer test

# Run with coverage
vendor/bin/pest --coverage

# Run specific test file
vendor/bin/pest tests/Unit/ValidationServiceTest.php

# Run tests with filter
vendor/bin/pest --filter="validation"
```

### Code Quality

[](#code-quality)

```
# Check code style
composer cs:check

# Fix code style
composer cs

# Run static analysis
composer analyse

# Run all checks
composer check
```

### Available Make Commands

[](#available-make-commands)

```
make help              # Show available commands
make install           # Install dependencies
make test              # Run tests
make test-coverage     # Run tests with coverage
make lint              # Check code style
make fix               # Fix code style issues
make phpstan           # Run static analysis
make all               # Run all checks
make hooks-install     # Install git hooks
make demo              # Show tool demonstration
```

🔄 Integration with CI/CD
------------------------

[](#-integration-with-cicd)

### GitHub Actions

[](#github-actions)

```
name: Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: 8.3
          coverage: xdebug
      - name: Install dependencies
        run: composer install --no-progress --no-suggest --prefer-dist --optimize-autoloader
      - name: Run tests
        run: composer test
      - name: Run static analysis
        run: composer analyse
      - name: Check code style
        run: composer cs:check
      - name: Validate commit messages
        run: vendor/bin/php-commitlint validate "${{ github.event.head_commit.message }}"
```

### GitLab CI

[](#gitlab-ci)

```
stages:
  - test
  - validate

test:
  stage: test
  image: php:8.3
  before_script:
    - apt-get update && apt-get install -y git unzip
    - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
    - composer install
  script:
    - composer test
    - composer analyse

validate-commits:
  stage: validate
  image: php:8.3
  script:
    - composer install
    - vendor/bin/php-commitlint validate "$CI_COMMIT_MESSAGE"
```

🚨 Error Codes
-------------

[](#-error-codes)

PHP CommitLint uses specific exit codes for different error conditions:

- **`0`** - Success
- **`1`** - Validation failed
- **`2`** - Configuration error
- **`3`** - File system error
- **`4`** - Invalid argument
- **`5`** - Runtime error
- **`6`** - Permission denied
- **`7`** - Not a Git repository

🔒 Security Features
-------------------

[](#-security-features)

- **Input validation** for all commit message processing
- **Safe command execution** using Symfony Process component
- **Configuration validation** to prevent malicious configs
- **Path traversal protection** in file operations
- **File size limits** (100KB max for config files)
- **No eval() or dynamic code execution**
- **Command validation** prevents dangerous operations in custom hooks

🤝 Contributing
--------------

[](#-contributing)

We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.

### Quick Start for Contributors

[](#quick-start-for-contributors)

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Make your changes and add tests
4. Run the test suite (`composer test`)
5. Check code style (`composer cs:check`)
6. Run static analysis (`composer analyse`)
7. Commit your changes (`git commit -m "feat: add amazing feature"`)
8. Push to the branch (`git push origin feature/amazing-feature`)
9. Open a Pull Request

📄 License
---------

[](#-license)

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

🙏 Acknowledgments
-----------------

[](#-acknowledgments)

- Inspired by [husky](https://github.com/typicode/husky) and [commitlint](https://github.com/conventional-changelog/commitlint)
- Built with [Symfony Console](https://symfony.com/doc/current/components/console.html)
- Tested with [Pest](https://pestphp.com/)

📚 Documentation
---------------

[](#-documentation)

- 📖 **[API Documentation](docs/API.md)** - Detailed API reference for developers
- ❓ **[FAQ](docs/FAQ.md)** - Frequently asked questions and troubleshooting
- 🤝 **[Contributing Guide](CONTRIBUTING.md)** - How to contribute to the project
- 📋 **[Changelog](CHANGELOG.md)** - Release notes and version history
- 🔒 **[Security Policy](SECURITY.md)** - Security guidelines and reporting

📞 Support
---------

[](#-support)

- 📧 Email:
- 🐛 Issues: [GitHub Issues](https://github.com/dev-kraken/php-commitlint/issues)
- 💬 Discussions: [GitHub Discussions](https://github.com/dev-kraken/php-commitlint/discussions)
- ❓ FAQ: [Frequently Asked Questions](docs/FAQ.md)

---

Made with ❤️ by [DevKraken](https://github.com/dev-kraken)

###  Health Score

33

—

LowBetter than 75% of packages

Maintenance52

Moderate activity, may be stable

Popularity9

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

332d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/d335791dfe7c83d3da2ae406e4e6cbcd963e7d5d4b0dfaed5f6fd87450c2fbd8?d=identicon)[devkraken](/maintainers/devkraken)

---

Top Contributors

[![dev-kraken](https://avatars.githubusercontent.com/u/86368498?v=4)](https://github.com/dev-kraken "dev-kraken (26 commits)")

---

Tags

phpvalidationcode qualitylintgithookscommitdeveloper-toolsconventional-commitsgit-hookscommitlinthusky

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/dev-kraken-php-commitlint/health.svg)

```
[![Health](https://phpackages.com/badges/dev-kraken-php-commitlint/health.svg)](https://phpackages.com/packages/dev-kraken-php-commitlint)
```

###  Alternatives

[captainhook/captainhook

PHP git hook manager

1.1k6.8M370](/packages/captainhook-captainhook)[marcocesarato/php-conventional-changelog

Generate changelogs and release notes from a project's commit messages and metadata and automate versioning with semver.org and conventionalcommits.org

2511.3M109](/packages/marcocesarato-php-conventional-changelog)[ramsey/conventional-commits

A PHP library for creating and validating commit messages according to the Conventional Commits specification. Includes a CaptainHook action!

1931.2M122](/packages/ramsey-conventional-commits)[playwright-php/playwright

Modern PHP library for Playwright automation: browsing, scraping, screenshots, testing, and more.

7613.0k5](/packages/playwright-php-playwright)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
