# Conventional Commits Quick Reference

*Commit message format, types, scopes, breaking changes*

> Source: Conventional Commits (conventionalcommits.org) · MIT

## Format

### Commit Message Structure

```
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
```

### Parts Explained

| Command | Description |
|---------|-------------|
| `type` | Category of change (feat, fix, etc.) |
| `scope` | Section of codebase affected (optional) |
| `description` | Short summary in imperative mood |
| `body` | Detailed explanation (optional, after blank line) |
| `footer` | Metadata like BREAKING CHANGE or issue refs |

### Rules

| Command | Description |
|---------|-------------|
| `Imperative mood` | "add feature" not "added feature" |
| `Lowercase type` | feat: not Feat: |
| `No period` | Description does not end with "." |
| `Blank line` | Separate body/footer from description |

## Types

### Core Types (SemVer-relevant)

| Command | Description |
|---------|-------------|
| `feat` | New feature (triggers MINOR version bump) |
| `fix` | Bug fix (triggers PATCH version bump) |

### Extended Types (Common Convention)

| Command | Description |
|---------|-------------|
| `build` | Build system or external dependencies |
| `chore` | Maintenance tasks (no src/test changes) |
| `ci` | CI configuration and scripts |
| `docs` | Documentation only changes |
| `perf` | Performance improvement |
| `refactor` | Code change that neither fixes nor adds |
| `revert` | Reverts a previous commit |
| `style` | Formatting, whitespace (not CSS styling) |
| `test` | Adding or correcting tests |

## Scope

### Scope Usage

```
feat(auth): add OAuth2 login flow
fix(parser): handle empty input gracefully
docs(readme): update installation steps
refactor(api): extract validation middleware
```

### Scope Guidelines

| Command | Description |
|---------|-------------|
| `Module name` | feat(auth):, fix(parser): |
| `Layer name` | feat(api):, fix(db): |
| `Feature area` | feat(search):, fix(checkout): |
| `Dependency` | build(deps):, chore(npm): |
| `Omit if broad` | Use no scope for cross-cutting changes |

## Breaking Changes

### Marking Breaking Changes

```
feat!: remove deprecated login endpoint
feat(api)!: change response format to JSON:API
fix!: drop Node 14 support
```

### Footer-Style Breaking Change

```
feat(api): change user endpoint response
BREAKING CHANGE: response now returns array
instead of object. Update client parsing.
```

### Rules

| Command | Description |
|---------|-------------|
| `! after type/scope` | Shorthand breaking change marker |
| `BREAKING CHANGE:` | Footer token (always uppercase) |
| `BREAKING-CHANGE:` | Also valid (hyphen form) |
| `SemVer impact` | Triggers MAJOR version bump |
| `Any type` | Breaking changes can apply to any type |

## Examples

### Simple Commits

```
feat: add email notifications
fix: prevent race condition in checkout
docs: correct typo in contributing guide
style: format with prettier
refactor: simplify error handling logic
```

### With Scope

```
feat(blog): add comment threading
fix(auth): refresh token before expiry
test(api): add missing edge case coverage
ci(github): add Node 20 to test matrix
```

### With Body and Footer

```
fix(parser): handle nested quotes correctly

Previously, nested quotes caused the parser
to enter an infinite loop. This adds a depth
counter to prevent unbounded recursion.

Closes #234
```

## Footer

### Footer Tokens

| Command | Description |
|---------|-------------|
| `BREAKING CHANGE:` | Describes breaking API change |
| `Closes #123` | Auto-close issue on merge |
| `Fixes #456` | Auto-close issue (fix reference) |
| `Refs #789` | Reference issue without closing |
| `Reviewed-by: name` | Reviewer attribution |
| `Co-authored-by: name` | Co-author attribution |

### Multiple Footers

```
feat(api)!: redesign authentication flow

Migrate from session-based to JWT auth.

BREAKING CHANGE: /auth endpoints changed
Closes #101
Refs #98, #99
```

## Tooling

### Commit Linting

```
npm install -D @commitlint/cli \
  @commitlint/config-conventional
echo "module.exports = { extends: \
  ['@commitlint/config-conventional'] }" \
  > commitlint.config.js
```

### Popular Tools

| Command | Description |
|---------|-------------|
| `commitlint` | Lint commit messages against convention |
| `husky` | Git hooks (run commitlint on commit) |
| `commitizen (cz)` | Interactive commit message builder |
| `standard-version` | Auto changelog + version bump |
| `semantic-release` | Fully automated release pipeline |
| `release-please` | Google's release automation tool |

### Commitizen Setup

```
npm install -D commitizen \
  cz-conventional-changelog
npx commitizen init cz-conventional-changelog
# Use: npx cz (or git cz with alias)
```

## Common Patterns

### Version Bump Mapping

| Command | Description |
|---------|-------------|
| `fix:` | PATCH (1.0.0 → 1.0.1) |
| `feat:` | MINOR (1.0.0 → 1.1.0) |
| `BREAKING CHANGE` | MAJOR (1.0.0 → 2.0.0) |
| `docs:, style:, etc.` | No version bump |

### Changelog Grouping

```
## [1.2.0] - 2026-03-27
### Features
- add email notifications (abc1234)
### Bug Fixes
- prevent race condition (#123) (def5678)
```

### Revert Format

```
revert: feat(blog): add comment threading
This reverts commit abc1234def5678.
```
