| name | conventional-commits |
| description | Format commit messages using the Conventional Commits v1.0.0 specification. Use when writing commit descriptions, generating commit messages, or when the user asks about commit message format. |
Conventional Commits v1.0.0
All commit messages MUST follow this format:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Types
| Type | Purpose | SemVer |
|---|
feat | A new feature | MINOR |
fix | A bug fix | PATCH |
build | Changes to the build system or dependencies | — |
chore | Maintenance tasks, no production code change | — |
ci | CI configuration and scripts | — |
docs | Documentation only | — |
style | Formatting, whitespace, semicolons (not CSS) | — |
refactor | Code change that neither fixes nor adds | — |
perf | Performance improvement | — |
test | Adding or correcting tests | — |
Rules
- The type is required and must be a noun (
feat, fix, etc.).
- An optional scope may follow the type in parentheses:
feat(parser):.
- A colon and space (
: ) MUST follow the type/scope prefix.
- The description is a short summary immediately after
: .
- An optional body provides detail and MUST begin one blank line after the description.
- An optional footer MUST begin one blank line after the body (or description if no body).
- Footers use the format
token: value or token #value (inspired by git trailers).
- Footer tokens use
- in place of spaces (except BREAKING CHANGE).
- A BREAKING CHANGE is indicated by either:
- A ! immediately before the
: — e.g. feat!: or feat(api)!:
- A footer:
BREAKING CHANGE: <description>
- Both may be used together; the footer provides the detailed explanation.
BREAKING CHANGE MUST be uppercase. BREAKING-CHANGE is also allowed.
- Breaking changes map to a MAJOR SemVer bump.
- Types other than
feat and fix are permitted (the table above is conventional, not exhaustive).
- Units of information beyond the spec MUST NOT be treated as different by tooling, except for
BREAKING CHANGE.
- Changes to
SKILL.md files are never docs. They are configuration/tooling — use chore for maintenance edits or feat for new capabilities.
- Scope should name the broad system or component being changed (e.g.
claude, api, auth), not the specific file or sub-skill. Prefer the parent package or module name.
- Never include anything in the commit message that indicates AI involvement — no
Co-Authored-By footers, no model names (e.g. Claude, Opus), no Generated by lines, no tool attribution. Commit messages must read as if written by a human.
Examples
Simple feature:
feat: add email notifications for new signups
Feature with scope:
feat(auth): support OAuth2 PKCE flow
Fix with body:
fix(parser): handle nested brackets in expressions
The regex previously failed on inputs containing consecutive
closing brackets. Switch to a recursive descent approach.
Breaking change (bang and footer):
feat(api)!: remove deprecated /v1/users endpoint
BREAKING CHANGE: The /v1/users endpoint has been removed.
Clients must migrate to /v2/users.
Chore with scope:
chore(deps): bump tokio from 1.37 to 1.38
Docs:
docs: clarify rate-limit behavior in README