Understanding Conventional Commits

A primer on the Conventional Commits spec and how it produces a clear, consistent commit history.


When working on a project, especially in a team setting, it’s crucial to have a clear and understandable commit history. Enter “Conventional Commits”, a specification for adding human and machine-readable meaning to commit messages.

What are Conventional Commits?

Conventional Commits is a commit message convention that provides an easy set of rules for creating consistent commit messages. It’s a standardized format that makes it simpler to:

  • Automatically generate changelogs.
  • Automatically determine semantic version bumps (based on the types of commits).
  • Navigate and understand the history of a project.

The Basic Structure

A conventional commit message consists of a header, and optionally a body and a footer. The header has a special format:

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]
  • type: Represents the nature of the change (e.g., feat, fix, chore, docs, style, refactor, perf, test).
  • scope: (Optional) Represents the module or feature affected by the change.
  • short description: A succinct description of the change.
feat(button): add a mute icon to the video button
fix(player): handle user autoplay restrictions
refactor(utils): rework the calculation method
docs(readme): add usage section

Why Use Conventional Commits?

  1. Clarity & Focus: Each commit has a clear purpose, making it easier to review and understand the context.

  2. Automation: Tools like standard-version or semantic-release can use the commit messages to automatically generate changelogs and determine version bumps.

  3. Collaboration: It provides a unified way of committing changes, ensuring that everyone in the team is on the same page.

Common Types

  • feat: A new feature. (this correlates with MINOR in Semantic Versioning).
  • fix: A bug fix. (this correlates with PATCH in Semantic Versioning)
  • docs: Documentation changes.
  • build: Build related changes.
  • ci: For CI/CD related changes.
  • style: Code style changes (e.g., formatting).
  • refactor: Code changes that neither fix a bug nor add a feature.
  • perf: Performance improvements.
  • test: Adding or modifying tests.
  • chore: Maintenance tasks, updates, etc.

Breaking Changes

Sometimes you might introduce changes that break backward compatibility. These are often denoted with BREAKING CHANGE in the commit footer:

feat(database): change the database schema

BREAKING CHANGE: modifies the database schema which isn't backward compatible.

or appends a ! after the type/scope, introduces a breaking API change (correlating with MAJOR in Semantic Versioning). A BREAKING CHANGE can be part of commits of any type.

Tools Supporting Conventional Commits

Several tools support or advocate for the Conventional Commits specification:

  • Commitizen: An interactive tool to create commit messages.
  • standard-version: Auto-bump versions and generate changelogs based on commit messages.
  • semantic-release: Fully automated version management and package publishing.

Conclusion

Adopting Conventional Commits can be a game-changer, especially for larger projects or teams. While it might take a bit to get used to, the benefits in terms of clarity, automation, and collaboration are immense. Give it a try and bring consistency and clarity to your commit messages!