DEV Community

Ibad ur Rehman
Ibad ur Rehman

Posted on

Conventional Commits: a beginner’s guide to writing useful commit messages

A commit message is a small note to whoever reads your code history next. Sometimes, that person is you, three months later, trying to understand why something changed.

Messages like update code or fix stuff don’t leave much to work with.

Conventional Commits gives those messages a simple, consistent structure. Here’s how it works, and where it helps.

The basic format

type(scope): description
Enter fullscreen mode Exit fullscreen mode

For example:

feat(goals): add a daily learning target
Enter fullscreen mode Exit fullscreen mode

There are three parts:

  • Type: the kind of change.
  • Scope: the part of the project affected. This is optional.
  • Description: a short explanation of what changed.

You can also add a body when the change needs more context.

Types you’ll commonly see

Type Typical use Example
feat A new feature feat(dashboard): add weekly learning totals
fix A bug fix fix(timer): stop tracking when the tab loses focus
docs Documentation docs: explain how to install the extension
refactor Restructuring without changing behavior refactor(timer): extract session calculations
test Test changes test(streaks): cover consecutive learning days
chore Maintenance chore: update development dependencies

The specification defines feat and fix; other types are allowed, so teams can agree on additional categories that suit their work.

These are illustrative examples for a learning tracker, rather than a list of actual commits.

The description still does most of the work

Compare:

fix: fix timer
Enter fullscreen mode Exit fullscreen mode

with:

fix(timer): exclude time spent in background tabs
Enter fullscreen mode Exit fullscreen mode

Both follow the format. The second tells you what behavior changed.

A useful question before committing is:

Could someone understand the purpose of this change without opening the diff?

For changes involving a tradeoff or a surprising decision, add the reasoning in the body:

fix(streaks): count learning days independently of daily goals

A learner can study without reaching their daily target.
Use tracked activity to determine whether the day contributes
to their streak.
Enter fullscreen mode Exit fullscreen mode

That explanation preserves a product decision that the code alone might not make obvious.

What about breaking changes?

A breaking change requires consumers to adapt their existing usage. You can mark it with ! before the colon and explain the migration in a footer:

feat(config)!: replace trackingInterval with trackingIntervalMs

BREAKING CHANGE: Rename trackingInterval to trackingIntervalMs
and provide its value in milliseconds instead of seconds.
Enter fullscreen mode Exit fullscreen mode

Under the convention’s Semantic Versioning mapping, fixes correspond to patch releases, features to minor releases, and breaking changes to major releases. Release automation needs to be configured to apply those rules.

Why use this?

A consistent structure can help people scan project history. It also gives tools predictable information for generating changelogs and determining version bumps.

You can start by writing messages manually. A commit-message linter or release pipeline can come later if it solves a problem in your workflow.

Where the convention falls short

A Hacker News discussion about Conventional Commits raised a useful concern: it’s possible to spend more effort categorizing a change than explaining it.

Adding fix: to an unclear message doesn’t make it informative. And a generated changelog may still need editing before it helps users understand a release.

My takeaway is to keep the format simple and put care into the description and reasoning. The convention provides structure; the writer provides context.

For your next commit, try:

type: describe the specific change
Enter fullscreen mode Exit fullscreen mode

Add a scope if it helps, and a body if there’s reasoning worth preserving.

Do you use Conventional Commits in your projects? Has the structure helped you, or do you prefer another approach?

Top comments (0)