Conventional Commits
- Pronunciation
- kun-VEN-shuh-nul kuh-MITS
In short
Conventional Commits is a specification for structured commit messages like feat: add search, so tools can write changelogs and pick versions automatically.
What are Conventional Commits?
A conventional commit message starts with a type, an optional scope and a short description: feat(auth): add passkey login or fix: prevent double payment. The most common types are feat for new features and fix for bug fixes, with others such as docs, refactor, test, perf, build, ci and chore for changes that don't affect users directly.
Breaking changes are marked with an exclamation mark after the type, as in feat!: drop support for Node 18, or with a BREAKING CHANGE: footer. Because each type has a meaning, the history maps directly onto semantic versioning: fixes trigger a patch release, features a minor release, and breaking changes a major one.
The specification, version 1.0.0 published in 2019, grew out of the commit guidelines of the Angular project. Tools build on it: commitlint checks messages in a Git hook or CI, and semantic-release or release-please read the history to bump versions, write the changelog and publish releases without manual work.
A common misconception is that the convention is only bureaucracy. A consistent format makes history easier to scan and search, but it works best when commits are small and focused. A single commit that mixes a feature, a fix and a refactor can't be labeled honestly with one type.
Key takeaways
- Conventional Commits defines a structured commit message format.
- Messages look like type(scope): description, such as feat: or fix:.
- A ! or a BREAKING CHANGE footer marks breaking changes.
- Types map to semantic versioning: fix is patch, feat is minor, breaking is major.
- Tools such as commitlint and semantic-release automate checks and releases.
Example
feat(search): add fuzzy matching for typos
fix(cart): prevent negative totals with stacked coupons
docs: explain how to run the e2e tests
refactor(api): extract pagination helper
perf(images): serve AVIF when the browser supports it
feat(auth)!: require passkeys for admin accounts
BREAKING CHANGE: password-only login is no longer accepted for admins.Readers ask
What are the Conventional Commits types?
The specification requires feat and fix. Common additional types, taken from the Angular convention, are docs, style, refactor, perf, test, build, ci, chore and revert.
How do Conventional Commits relate to semantic versioning?
A fix commit corresponds to a patch release, a feat commit to a minor release, and any commit marked as a breaking change to a major release, so tools can calculate the next version from the history.
How do I enforce Conventional Commits?
Use commitlint in a commit-msg Git hook, for example with Husky, and in CI to reject messages that don't follow the format. Squash-merge workflows can also check the pull request title instead.
See also
- CommitVersion Control, p. 5A commit is a saved snapshot of a project's files in Git, recorded with a unique ID, an author, a timestamp, and a message describing what changed.
- Semantic VersioningVersion Control, p. 35Semantic versioning is a MAJOR.MINOR.PATCH numbering scheme in which each part signals whether a release breaks compatibility, adds features, or fixes bugs.
- Git HooksVersion Control, p. 16Git hooks are scripts that Git runs automatically at certain points, such as before a commit or a push, to check code, enforce rules, or automate tasks.
- Squash MergeVersion Control, p. 36A squash merge combines all the commits from a branch into one new commit on the target branch, keeping the main history short and easy to read.
- CI/CDDevOps & Cloud, p. 9CI/CD is a set of automated practices that build, test, and release code changes frequently, so software can be delivered to users quickly and safely.
- Code ReviewVersion Control, p. 4A code review is the practice of having other developers check code changes before they are merged, to catch bugs, improve quality, and share knowledge.
Spotted a mistake or something missing on this page?Suggest an edit