Documentation
Git Workflow
Commit Messages

Commit Messages

Conventional Commits format for clear history.

Format

<type>(<scope>): <subject>

[optional body]

[optional footer]

Types

TypePurposeChangelog
featNew featureMinor version bump
fixBug fixPatch version bump
docsDocumentation onlyNo version bump
styleFormatting, whitespaceNo version bump
refactorCode change, no behavior changeNo version bump
perfPerformance improvementPatch version bump
testAdding testsNo version bump
buildBuild system changesNo version bump
ciCI configurationNo version bump
choreMaintenance tasksNo version bump
revertRevert previous commitVaries

Scopes

Common scopes for React projects:

ScopeUsage
authAuthentication features
usersUser management
uiUI components
apiAPI services
configConfiguration
depsDependencies

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.2

With Body

feat(auth): implement OAuth2 login
 
Add Google and GitHub OAuth providers.
Includes token refresh and session management.
 
Closes #123

Breaking Change

feat(api)!: change response format
 
BREAKING CHANGE: API responses now use `data` wrapper.
 
Before: { users: [...] }
After: { data: { users: [...] } }

Rules

  1. Imperative mood — "add feature" not "added feature"
  2. Lowercase — Type and scope in lowercase
  3. No period — Subject line doesn't end with period
  4. Max 72 chars — Subject line length limit
  5. Blank line — Between subject and body

Bad Examples

# ❌ Avoid
updated stuff
WIP
fix bug
FEAT: Add feature
feat(auth): Added new login.
misc changes

Commitlint 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 $1

Git Aliases

# ~/.gitconfig
[alias]
  cm = commit -m
  co = checkout
  br = branch
  st = status
  lg = log --oneline --graph --decorate