---
title: Conventional Commit types
description: The prefix that starts a commit message, what each one means, and when to reach for it.
tags: [git, commits, conventions]
type: blog
date: 2026-08-30
---

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

| Type       | Use it when                                                                                                     |
| ---------- | --------------------------------------------------------------------------------------------------------------- |
| `feat`     | A new feature ships with the change.                                                                            |
| `fix`      | A bug is fixed.                                                                                                 |
| `chore`    | Something changed that isn't a fix or feature and doesn't touch `src` or test files, like bumping a dependency. |
| `refactor` | Code was reworked without fixing a bug or adding a feature.                                                     |
| `docs`     | Only documentation changed, like the README or other markdown.                                                  |
| `style`    | Formatting only, nothing that changes what the code does: whitespace, missing semicolons, and the like.         |
| `test`     | Tests were added or corrected.                                                                                  |
| `perf`     | A change that makes things faster.                                                                              |
| `ci`       | Continuous integration config or scripts.                                                                       |
| `build`    | The build system or external dependencies.                                                                      |
| `revert`   | Undoes 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.
