EMZETT.
Login

Conventional Commits

In short: A convention for commit messages with a fixed format: <type>(<scope>): <short description>, e.g. feat(shop): ... or fix(chat): ....

In more detail: Common types: feat (new feature), fix (bug fix), refactor (restructuring without behaviour change), chore (maintenance such as dependency updates), perf (performance). Makes the commit history machine-readable (e.g. for automatic changelogs) and easy for humans to categorise at a glance.

Our context: A dedicated convention was agreed for Emzett — every change “batch” gets a commit message in this format in German, plus an additional “why” section with the reasoning behind the decision.

In Depth

Complete structure

Besides the one-line header, the full specification also knows an optional body (a more detailed explanation, usually separated by a blank line) and optional “footers” for structured additional information — e.g. BREAKING CHANGE: ... for changes that affect existing users of the codebase, or Closes #123 to automatically link a commit to an issue. A ! directly after type/scope (feat(api)!: ...) also marks a breaking change, as a shorthand for the detailed footer.

feat(shop)!: switch cart API to new response format

Old clients expecting the previous format break with this
update - only affects internal consumers of the API, no external ones.

BREAKING CHANGE: /api/cart now returns { items: [...] } instead of a
raw array.
Closes #142

Automation through a machine-readable structure

The real practical benefit shows up with tools that evaluate this structure automatically: semantic-release and similar tools can derive the next version number following semantic versioning directly from the commit history — a feat commit bumps the minor version, a commit with BREAKING CHANGE the major version, fix only the patch version — and generate a readable changelog from it straight away, without anyone having to note down manually what changed in which version. However, this only works reliably if REALLY every commit in the repository follows the convention — even a single commit without the correct prefix can disrupt the automatic evaluation or lead to a wrongly calculated version number.

Other common types

Besides the core types (feat, fix, refactor, chore, perf), further conventions have become established in practice, even though they’re not part of the official specification: docs (pure documentation changes), test (adding/changing tests without changing production code), style (purely cosmetic changes such as formatting, without behaviour change), and build/ci (changes to the build configuration or continuous integration pipelines). The scope in brackets is optional but helpful for seeing at a glance which part of the codebase is affected without having to read the whole diff — in larger projects with clearly separated modules (e.g. shop, chat, auth) this makes the commit history much more searchable.

Limits of the convention

Conventional Commits enforces structure, but not quality — a technically correctly formatted commit (fix(shop): fixed bug) can still say nothing of substance if the actual cause or reasoning is missing. That’s why many teams supplement the pure type/scope structure with the obligation to briefly explain the “why” in the body (not just the “what”, which can be read from the diff anyway) — in the long run, commit messages are often the only place where the motivation behind a decision stays documented.

See also: Next.js App Router, Git