Commitizen — Standardized Commit Messages
Overview
Commitizen enforces the Conventional Commits specification for git commit messages. It provides an interactive CLI prompt for crafting compliant messages, integrates with CI to validate commit messages, and enables automatic changelog generation and semantic versioning from commit history.
When to Use
- Enforcing commit message standards across a team
- Enabling automated changelogs (see changesets-versioning)
- Automating semantic version bumps based on commit types
- Making
git logreadable and machine-parseable - Setting up release automation pipelines
Installation
# Global installation (for the interactive CLI)
npm install -g commitizen cz-conventional-changelog
# Configure globally
echo '{ "path": "cz-conventional-changelog" }' > ~/.czrc
# Project-level installation
npm install --save-dev commitizen cz-conventional-changelog
# Initialize project config
npx commitizen init cz-conventional-changelog --save-dev --save-exact
Key Patterns
Conventional Commits format
<type>(<scope>): <subject>
<body>
<footer>
Types:
feat— new feature (triggers MINOR bump)fix— bug fix (triggers PATCH bump)docs— documentation onlystyle— formatting, no code changerefactor— refactoringtest— adding testschore— maintenance tasksperf— performance improvementsci— CI configuration changesbuild— build system changesBREAKING CHANGE— in footer (triggers MAJOR bump)
Using the interactive prompt
# Use `git cz` instead of `git commit`
git add .
git cz
# Or via npx
npx cz
# Interactive prompt:
# ? Select the type of change: feat
# ? What is the scope? auth
# ? Short description: add OAuth2 login flow
# ? Longer description? (optional)
# ? Breaking changes? No
# ? Issues closed? #42
package.json configuration
{
"scripts": {
"commit": "cz"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
},
"devDependencies": {
"commitizen": "^4.3.0",
"cz-conventional-changelog": "^3.3.0",
"@commitlint/cli": "^19.0.0",
"@commitlint/config-conventional": "^19.0.0"
}
}
Validating with commitlint
// commitlint.config.js
module.exports = {
extends: ["@commitlint/config-conventional"],
rules: {
"type-enum": [
2,
"always",
["feat", "fix", "docs", "style", "refactor", "test", "chore", "perf", "ci", "build", "revert"],
],
"scope-case": [2, "always", "kebab-case"],
"subject-max-length": [2, "always", 72],
},
};
Integration with Lefthook (commit-msg hook)
# lefthook.yml
commit-msg:
commands:
commitlint:
run: npx commitlint --edit {1}
Integration with GitHub Actions
# .github/workflows/commitlint.yml
name: Commitlint
on: [push, pull_request]
jobs:
commitlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: wagoid/commitlint-github-action@v5
Example compliant commits
# Feature with scope
git commit -m "feat(auth): add password strength indicator"
# Bug fix referencing issue
git commit -m "fix(api): handle null response from payment gateway
Fixes #234
The payment gateway occasionally returns null instead of an error
object when the card is declined."
# Breaking change
git commit -m "feat(api)!: remove deprecated v1 endpoints
BREAKING CHANGE: The /api/v1/* endpoints have been removed.
Migrate to /api/v2/* before upgrading."
# Chore
git commit -m "chore(deps): update dependencies to latest versions"
Common Pitfalls
- Scope consistency: Define allowed scopes in
commitlint.config.jsto prevent drift. - Breaking changes: Must appear either as
!after type/scope OR in the footer asBREAKING CHANGE:. - Subject tense: Use imperative mood ("add feature" not "added feature").
- Long subjects: Keep the subject under 72 characters; use the body for detail.
- Merge commits: Commitlint may reject auto-generated merge commit messages — configure
ignoresfor merge commits.
Related Skills
- lefthook-git-hooks — enforce commitlint via git hooks
- changesets-versioning — monorepo versioning using conventional commits
- changelog-generator — auto-generate changelogs from commit history
GitNexus Index
domain: developer-tooling
maturity: stable
complexity: low
spec: conventional-commits
config-files: .czrc, commitlint.config.js, package.json
integrates-with: lefthook, github-actions, semantic-release