Conventional Commit Generator

Pick a type, add a scope, flag the breaking change, copy the message. Conventional Commits without the syntax anxiety — with a live preview, a subject-length coach, and every one of the eleven types explained as you pick it.

git 100% client-side 11 types live preview
Composer conventionalcommits.org spec

feat → a new user-facing feature

0 / 50

Imperative mood — "add", not "added". No trailing period.

Ctrl/⌘ + Enter anywhere in the form copies the finished message.

Live preview

            
subject ≤ 50 chars imperative mood body wraps at 72

Use it in three steps

  1. Pick the type

    Choose from the eleven types — a one-line explanation appears under the dropdown so you never guess twice.

  2. Describe the change

    Write the subject in imperative mood and watch the counter keep it under 50 characters. Add body and footer if the change deserves them.

  3. Copy and commit

    The preview assembles everything to spec — scope, breaking bang, blank lines and all. Ctrl/⌘+Enter copies it straight to your clipboard.

How to use this generator

Choose a type from the dropdown — the hint line underneath tells you exactly when each one belongs, so refactor and chore stop being a coin flip. Add a scope if your project uses them, write the subject in imperative mood, and watch the counter: green under 50 characters, amber past it, red where git's UI will start truncating you.

Flip the breaking-change toggle and the tool adds the ! and pre-fills a BREAKING CHANGE: footer for you to finish. The preview on the right assembles everything to spec — blank lines included — and Ctrl/⌘+Enter copies it anywhere in the form. Paste into git commit, or pipe straight into git commit -m "$(pbpaste)" if you're feeling fancy.

What Conventional Commits actually are

Conventional Commits is a lightweight convention for writing git commit messages so that both humans and machines can read them. The shape is tiny — type(scope)!: description, an optional body, an optional footer — but that small discipline unlocks a lot.

It grew out of the AngularJS commit guidelines of the mid-2010s, was formalized at conventionalcommits.org, and reached version 1.0.0 in 2019. The core promise: your commit history becomes structured data. Tools like semantic-release and standard-version read the types and derive everything else — feat commits bump the minor version, fix commits bump the patch, and anything flagged BREAKING CHANGE bumps the major. Version numbers and changelogs stop being a Friday afternoon ritual and start being a side effect of commits you were writing anyway.

Even without automation, the payoff is a git log --oneline that reads like a table of contents: fix(api): handle empty gateway responses tells a reviewer what changed, where, and why it matters — before a single diff line loads. Six months later, when someone asks "when did the auth flow change?", the answer is one grep away instead of an archaeology project.

Anatomy of a Conventional Commit

A fully-loaded commit, every part labeled:

git log -1
# ┌ type   ┌ scope  ┌ breaking flag
# │        │        │        ┌ description (≤50 chars, imperative)
feat(auth)!: rotate refresh tokens on every use

# body — the WHY, wrapped at ~72 chars, separated by a blank line
Reusing refresh tokens let a leaked token grant access indefinitely.
Tokens are now single-use; the old one is invalidated the moment a
new one is issued.

# footer — breaking details + issue references
BREAKING CHANGE: /auth/refresh no longer returns the same token
Closes #234

Three structural rules do most of the work: the description is always on the first line, the body is always separated by a blank line, and footers use the Token: value or Token #value shape. Get those right and every tool in the ecosystem — commitlint, changelog generators, release bots — understands you without configuration.

The eleven types, decoded

  • feat — a new user-facing feature. Bumps the minor version under semantic-release.
  • fix — a bug fix. Bumps the patch version.
  • docs — documentation only: READMEs, guides, code comments. No code changed.
  • styleformatting: whitespace, semicolons, lint fixes. Nothing that changes logic — and despite the name, CSS work is usually a feat or fix.
  • refactor — production code restructured without changing behavior: renaming, extracting, simplifying.
  • perf — a change whose whole point is performance.
  • test — adding missing tests or correcting existing ones. No production code.
  • build — the build system and dependencies: bundler config, package upgrades, compile scripts.
  • ci — CI configuration: GitHub Actions, GitLab pipelines, Jenkinsfiles.
  • chore — housekeeping that touches neither production code nor tests: tooling, editor config, tidying.
  • revert — undoing a previous commit. Subject is revert: <original subject>; the body carries This reverts commit <hash>.

Why teams actually adopt this

  • Automatic changelogs — conventional-changelog walks the log and writes release notes grouped by type. No more "what even shipped this sprint?"
  • Hands-off versioning — semantic-release derives SemVer from commit types and publishes without a human touching a version file.
  • Enforcement at commit time — commitlint plus a husky pre-commit hook rejects non-conforming messages before they enter history, gently but firmly.
  • Monorepo sanity — scopes tell tooling which packages a commit touched, so CI builds and tests only what changed.
  • Faster reviews — reviewers know what kind of change to expect before opening the diff, and "why is this a refactor and not a feat?" becomes a one-line conversation.

Gotchas that trip up every team once

  • Imperative mood, always. "add feature", never "added feature" or "adds feature". It matches git's own generated messages — "Merge branch", "Apply patch".
  • 50 and 72 are real limits. git log --oneline truncates subjects around 50 characters; GitHub's UI wraps the body at 72. The counter above enforces the first one out of respect for your teammates' terminals.
  • No trailing period on the subject. It's a headline, not a sentence. Save the punctuation budget for the body.
  • style is not about CSS. It means code formatting. This single confusion produces half the mislabeled commits on earth.
  • One type per commit. If your subject needs the word "and", split the commit. Atomic commits are what make the whole convention pay off.
  • Breaking changes need detail. The ! flags it; the BREAKING CHANGE: footer explains what broke and how to migrate. Future-you is the audience.

Frequently asked questions

What's the difference between ! and the BREAKING CHANGE footer?

Both signal a breaking change, and the spec accepts either. The ! after the type or scope is the compact flag; the BREAKING CHANGE: footer is where you explain what broke and how to migrate. Tools like semantic-release watch for both — use the footer whenever there's detail worth writing.

Does the style type mean CSS changes?

No — the most common mix-up. style means code formatting: whitespace, semicolons, lint fixes, nothing that changes logic. An actual CSS change that alters how something looks or behaves is a feat or a fix.

refactor vs chore — which one?

refactor is production code that changed shape without changing behavior — renaming, extracting, restructuring. chore is everything around the code: dependencies, build scripts, tooling, housekeeping. If it touched src/ and changed nothing observable, it's a refactor.

Do I have to use a scope?

No, scope is optional. Use it when it genuinely helps — a module, component, or package name — and keep the vocabulary consistent across the project. feat: add login is fine; feat(auth): add login is better once the project has parts worth naming.

Past tense or present tense?

Imperative present: "add feature", not "added feature" or "adds feature". It matches the style git itself uses for generated messages — "Merge branch", "Apply patch" — and reads as an instruction to the codebase.

Does this work with any git workflow?

Yes — Conventional Commits is just a message convention, not a branching model. It layers onto trunk-based, GitFlow, or anything else. Teams that want enforcement add commitlint with a husky pre-commit hook; the messages themselves are plain git.