Conventional Commits is a lightweight commit message specification that unlocks automated changelog generation, semantic versioning, and dramatically improved repository history navigation. Adopting it costs engineering teams roughly two weeks of habit formation and pays dividends indefinitely through better tooling, clearer history, and eliminated manual versioning work.
What Is the Conventional Commits Standard?
Conventional Commits is a specification (conventionalcommits.org) for writing structured commit messages that follow a predictable format: a type prefix, an optional scope, and a description. The types are defined: feat (new feature), fix (bug fix), docs (documentation only), refactor (code change without feature or fix), perf (performance improvement), test (adding tests), chore (maintenance tasks), and ci (CI configuration changes). Breaking changes are indicated by an exclamation mark suffix (feat!:) or a BREAKING CHANGE: footer. This structured format is designed to be human-readable and machine-parseable, enabling the automation toolchain that makes Conventional Commits valuable.
<type>[optional scope]: <description>Examples:
feat(auth): add passkey authentication supportfix(api): correct rate limit calculation for burst requestsfeat!: remove deprecated v1 API endpointsCommit Message Format and Types
Core types and their semantics should be understood precisely to use Conventional Commits effectively. feat is reserved for commits that add new user-visible functionality — it triggers a minor version bump in semantic versioning. fix is for commits that correct incorrect behaviour — it triggers a patch version bump. refactor is for internal code changes that neither add features nor fix bugs — it does not trigger a version bump. Incorrect type usage (marking a feature as a chore to avoid version bumping, for example) defeats the automation toolchain.
Scopes are optional but valuable for monorepos and large projects. A scope in parentheses after the type indicates which component or domain the commit affects: feat(billing): add invoice PDF generation. Scopes enable filtered changelogs by component and help code reviewers and bisect users quickly identify relevant commits. Define allowed scopes explicitly in your contributing guidelines and enforce them via commit linting to prevent scope proliferation.
Breaking changes are the most critical convention to use correctly. Any commit that changes a public API in a non-backward-compatible way must be marked with either ! after the type (feat!:) or a BREAKING CHANGE: footer in the commit body. Breaking changes trigger a major version bump in semantic versioning. Unmarked breaking changes that slip into releases without major version increments are the most common source of library consumer frustration and the most important failure mode of poorly governed Conventional Commits adoption.
| Type | SemVer Impact | Changelog Section | Use When |
|---|---|---|---|
| feat | Minor bump (1.x.0) | Features | New user-facing functionality |
| fix | Patch bump (1.0.x) | Bug Fixes | Correcting incorrect behaviour |
| feat! / BREAKING CHANGE | Major bump (x.0.0) | Breaking Changes | Non-backward-compatible API changes |
| perf | Patch bump | Performance Improvements | Performance optimisations |
| docs | No bump | Documentation | Documentation-only changes |
| refactor | No bump | Code Refactoring | Internal changes, no behaviour change |
| test / ci / chore | No bump | Excluded by default | Tests, CI, maintenance |
Tooling Ecosystem: Enforcement and Automation
Commitlint is the standard tool for enforcing Conventional Commits format in CI and as a commit-msg git hook. Configured with @commitlint/config-conventional, it validates every commit message against the specification and rejects non-conforming commits before they enter the repository. Integrating commitlint as a Husky pre-commit hook ensures all commits on developer machines are validated before reaching remote branches.
Commitizen provides an interactive CLI that guides developers through composing Conventional Commits interactively, selecting type, entering scope, and writing description through a prompted workflow. It eliminates the need for developers to memorise the specification details during the adoption period and reduces type errors from developers who are not yet fluent with the format.
semantic-release is the fully automated release pipeline that conventional commits enable. Configured for a repository, it analyses commits since the last release, determines the correct version bump, generates a changelog, creates a git tag, and publishes to npm or another registry — all automatically on CI when commits merge to the release branch. Manual versioning and changelog writing become obsolete.
Release Please (Google's alternative to semantic-release) takes a PR-based approach: it creates a release PR when new conventional commits accumulate, which teams review and merge to trigger the release. This approach provides a human review gate before release without requiring manual release steps, balancing automation with oversight.
Automated Semantic Versioning with Conventional Commits
The connection between Conventional Commits and semantic versioning is the core value proposition for library and API maintainers. When all commits follow the specification, the version bump type is computable from the commit history: any feat! or BREAKING CHANGE commit since the last release triggers a major bump; any feat commit triggers at minimum a minor bump; any fix or perf commit triggers at minimum a patch bump. No human judgment required for versioning decisions.
This automation matters most for teams releasing frequently. A team releasing weekly that previously spent 2–3 hours per release on manual version determination and changelog writing saves 100–150 hours annually — equivalent to 2–3 engineering weeks — through full release automation. For open-source maintainers releasing irregularly, the changelog generation is often more valuable than the versioning automation, providing contributors and users a readable summary of every release without manual curation.
Team Adoption Strategy and Cultural Change
Conventional Commits adoption fails when it is perceived as bureaucracy rather than tooling that makes developers' work easier. Frame the adoption around the benefits developers directly experience: no more manually writing release notes, git log that is actually readable, and the ability to bisect issues by commit type without reading every commit message.
Gradual enforcement works better than big-bang mandates. Start with tooling available but optional for 2–4 weeks, allowing early adopters to build fluency while preparing the linting infrastructure. Enable commitlint as a warning (not blocking) for the next 4 weeks. Switch to hard enforcement once 80%+ of commits are naturally conformant — typically at the 6–8 week mark.
IDE integration via VS Code's git commit UI or commit convention extensions (Conventional Commits extension for VS Code, GitLens commit templates) significantly reduces friction for developers who prefer GUI git workflows to CLI. Lower the learning curve by meeting developers in their existing tools rather than requiring CLI adoption alongside convention adoption.
Implementation Roadmap
Add @commitlint/cli, @commitlint/config-conventional, and husky to the project. Configure a commit-msg hook that runs commitlint. Document allowed scopes for your project. Enable as warning-only initially to collect baseline conformance data.
Install commitizen with cz-conventional-changelog adapter. Configure git cz as the team's commit command. Run a 30-minute team session demonstrating the interactive commit workflow and explaining the type semantics. Answer questions about edge cases to prevent type confusion from solidifying into bad habits.
Implement semantic-release or Release Please in CI once the team has demonstrated consistent commit format compliance. Configure the changelog sections, release branch triggers, and publication targets. Run a dry-run release to validate the configuration before enabling automated publishing. Celebrate the first automated release with the team.
Switch commitlint to blocking mode once conformance rate consistently exceeds 95%. Roll out the tooling configuration to all team repositories using a shared config package to ensure consistency. Update contributing guidelines and PR templates to reinforce the convention for external contributors on open-source repositories.