PushBackLog

Conventional Commits

Soft enforcement Complete by PushBackLog team
Topic: clean-code Topic: process Topic: automation Skillset: backend Skillset: frontend Skillset: fullstack Skillset: devops Technology: generic Stage: execution

Conventional Commits

Status: Complete
Category: Clean Code
Default enforcement: Soft
Author: PushBackLog team


Tags

  • Topic: clean-code, process, automation
  • Skillset: backend, frontend, fullstack, devops
  • Technology: generic
  • Stage: execution

Summary

Conventional Commits is a lightweight specification for commit message structure that makes the history of a repository machine-readable and human-scannable. By encoding the type, scope, and breaking-change status of every commit in a structured format, teams can automate changelog generation, trigger semantic version bumps, and enforce a consistent vocabulary for code changes. It adds a negligible overhead to writing commits and yields significant returns in automation and communication.


Rationale

Commit messages are a communication medium

A commit message is documentation addressed to two audiences: the next human who reads the git log, and any automated system that processes changes. Unstructured commit messages like “fix stuff”, “wip”, “update”, or “changes” serve neither audience. A structured format with a consistent vocabulary tells the reader immediately what class of change occurred, where it occurred, and whether it is a breaking change.

Automation requires structure

Semantic release tooling (semantic-release, standard-version, changesets) can automatically determine the next version number and generate a changelog from commit history — but only if commits carry structured metadata. Conventional Commits provides the standard interface between commit history and these tools. A feat: commit triggers a minor version bump; a fix: triggers a patch; a BREAKING CHANGE: footer triggers a major bump.


Guidance

Format

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

Types

TypeWhen to use
featA new feature visible to users or API consumers
fixA bug fix
docsDocumentation changes only
styleFormatting, whitespace — no logic change
refactorCode change that neither fixes a bug nor adds a feature
perfPerformance improvements
testAdding or correcting tests
buildBuild system, package dependencies
ciCI/CD pipeline changes
choreMaintenance tasks that don’t fit the above
revertReverts a prior commit

Examples

feat(auth): add magic-link email login

Users can now authenticate using a passwordless magic link sent to their
registered email address. Falls back to password login if the email fails
to deliver within 5 minutes.

Closes #342
fix(billing): prevent duplicate charge on payment retry

Idempotency key was not being forwarded in the retry handler, causing
the payment gateway to process the charge twice on network timeout.

Fixes #489
feat(api)!: remove deprecated v1 endpoints

BREAKING CHANGE: /v1/users and /v1/orders are removed. Consumers must
migrate to /v2 equivalents. Migration guide: docs/v2-migration.md

Scope

The scope is a noun describing the part of the codebase affected: (auth), (billing), (api), (ci), (deps). Scopes should match the domain boundaries or module names of your codebase. Keep the list consistent — establish agreed scopes in your CONTRIBUTING guide.

Breaking changes

Breaking changes are marked with an exclamation mark after the type/scope (feat!:) or with a BREAKING CHANGE: footer in the commit body. Both trigger a major version bump in semantic release tooling.

Enforcement

Lint commit messages on every commit using commitlint:

// commitlint.config.js
module.exports = {
  extends: ['@commitlint/config-conventional']
};

Run in CI or via a commit-msg git hook (husky):

# .husky/commit-msg
npx --no -- commitlint --edit $1

Atomic commits and Conventional Commits

Conventional Commits work best when combined with atomic commits — each commit represents a single logical change. A commit that contains three unrelated changes cannot be classified under a single type accurately. The commit discipline enforces the commit structure discipline.