Brain
EngineeringGit

Conventional Commit types

The prefix that starts a commit message, what each one means, and when to reach for it.

A Conventional Commit starts with a type that says what kind of change this is. The format is type: short summary, optionally with a scope in parentheses, like fix(auth): reject expired tokens. The type is the part that tooling reads to sort changes and bump versions, so picking the right one matters more than it looks.

The types

TypeUse it when
featA new feature ships with the change.
fixA bug is fixed.
choreSomething changed that isn't a fix or feature and doesn't touch src or test files, like bumping a dependency.
refactorCode was reworked without fixing a bug or adding a feature.
docsOnly documentation changed, like the README or other markdown.
styleFormatting only, nothing that changes what the code does: whitespace, missing semicolons, and the like.
testTests were added or corrected.
perfA change that makes things faster.
ciContinuous integration config or scripts.
buildThe build system or external dependencies.
revertUndoes an earlier commit.

Picking between the close ones

A few types overlap enough to trip you up:

  • feat vs fix: if the behavior was never meant to work that way, it's a fix. If it's new ground, it's a feat.
  • refactor vs perf: both leave behavior alone, but perf is specifically for making something faster. Reach for perf only when speed is the point.
  • chore vs build: dependency bumps that don't touch how the app is built are chore. Changes to the build pipeline itself are build.
  • style vs refactor: style never changes meaning, only formatting. The moment logic moves, it's refactor.

Why bother

The prefix is a promise about scope. A reader scanning git log knows a fix line is worth a second look and a chore line usually isn't. Tools like semantic-release use the same signal: feat bumps the minor version, fix bumps the patch, and a BREAKING CHANGE footer bumps the major. Keep the types honest and the changelog writes itself.

On this page