Commit Messages
Conventional Commits format for clear history.
Format
<type>(<scope>): <subject>
[optional body]
[optional footer]Types
| Type | Purpose | Changelog |
|---|---|---|
feat | New feature | Minor version bump |
fix | Bug fix | Patch version bump |
docs | Documentation only | No version bump |
style | Formatting, whitespace | No version bump |
refactor | Code change, no behavior change | No version bump |
perf | Performance improvement | Patch version bump |
test | Adding tests | No version bump |
build | Build system changes | No version bump |
ci | CI configuration | No version bump |
chore | Maintenance tasks | No version bump |
revert | Revert previous commit | Varies |
Scopes
Common scopes for React projects:
| Scope | Usage |
|---|---|
auth | Authentication features |
users | User management |
ui | UI components |
api | API services |
config | Configuration |
deps | Dependencies |
Examples
Good Commits
feat(auth): add JWT token refresh
fix(users): resolve infinite loop in profile page
docs(readme): update installation instructions
refactor(api): simplify error handling logic
test(auth): add unit tests for login flow
chore(deps): upgrade React to v18.2With Body
feat(auth): implement OAuth2 login
Add Google and GitHub OAuth providers.
Includes token refresh and session management.
Closes #123Breaking Change
feat(api)!: change response format
BREAKING CHANGE: API responses now use `data` wrapper.
Before: { users: [...] }
After: { data: { users: [...] } }Rules
- Imperative mood — "add feature" not "added feature"
- Lowercase — Type and scope in lowercase
- No period — Subject line doesn't end with period
- Max 72 chars — Subject line length limit
- Blank line — Between subject and body
Bad Examples
# ❌ Avoid
updated stuff
WIP
fix bug
FEAT: Add feature
feat(auth): Added new login.
misc changesCommitlint Setup
pnpm add -D @commitlint/cli @commitlint/config-conventional// commitlint.config.js
export default {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
['feat', 'fix', 'docs', 'style', 'refactor', 'perf', 'test', 'build', 'ci', 'chore', 'revert'],
],
'scope-case': [2, 'always', 'lower-case'],
'subject-case': [2, 'always', 'lower-case'],
'subject-max-length': [2, 'always', 72],
},
};Husky Hook
# .husky/commit-msg
npx --no -- commitlint --edit $1Git Aliases
# ~/.gitconfig
[alias]
cm = commit -m
co = checkout
br = branch
st = status
lg = log --oneline --graph --decorate