Gitmoji + Conventional Commits
Produce commit messages that strictly follow Conventional Commits (commitlint config-conventional) prefixed with a Gitmoji shortcode. These rules are strict: follow them exactly, do not improvise an alternate format, and output only the commit message — no preamble, no explanation, no surrounding commentary. When presenting a message for the user to copy, a fenced code block is fine; when committing directly, pass the message through as-is.
Workflow
When asked to generate a commit:
- Determine what actually changed — from the staged diff, the changed files, or the user's description. Do not guess; if the change is ambiguous and you can inspect it, inspect it first.
- Pick the single most specific Gitmoji and its mapped
type. One commit = one logical change = one gitmoji. - Write the header (line 1) within the length limit.
- Add a body only when it adds real signal; add a footer only for breaking changes or issue references.
- Output the message and nothing else.
Format
<emoji_shortcode> <type>(<scope>): <subject>
<body>
<footer>
Header rules (line 1)
- Start with a Gitmoji shortcode like
:sparkles:(the literal:colon:form, NOT the unicode emoji ✨), followed by a single space. - Then
type(scope): subject. - Total length ≤ 72 characters.
- Subject in imperative mood, lowercase, no trailing period.
- Scope is optional; use it when it clearly identifies the affected area (folder, module, feature).
- For breaking changes, append
!after the scope or type:type(scope)!: subject.
Allowed types (commitlint config-conventional)
feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
Gitmoji to type mapping (pick the most specific match)
| Shortcode | Type | Use for |
|---|---|---|
:sparkles: | feat | new feature |
:bug: | fix | bug fix |
:ambulance: | fix | critical hotfix |
:adhesive_bandage: | fix | trivial fix |
:memo: | docs | documentation |
:lipstick: | style | UI / CSS |
:art: | style | code structure / formatting |
:recycle: | refactor | refactor |
:zap: | perf | performance |
:white_check_mark: | test | add/update tests |
:test_tube: | test | failing test |
:heavy_plus_sign: | build | add dependency |
:heavy_minus_sign: | build | remove dependency |
:arrow_up: | build | upgrade dependency |
:arrow_down: | build | downgrade dependency |
:wrench: | chore | config files |
:hammer: | chore | dev scripts |
:construction_worker: | ci | CI |
:green_heart: | ci | fix CI |
:rewind: | revert | revert |
:fire: | chore | remove code/files |
:truck: | refactor | rename or move files |
:rotating_light: | fix | linter warnings |
:lock: | fix | security |
:boom: | feat or refactor | breaking change |
:bookmark: | chore | release / version tag |
:rocket: | chore | deployment-related |
Body rules (optional, blank line after header)
- Explain WHAT and WHY, never HOW.
- Use a short paragraph for context, then a bullet list of concrete changes if there are several.
- Wrap lines at 72 characters.
- Imperative mood, same as the subject.
Footer rules (optional, blank line after body)
BREAKING CHANGE: <description>for breaking changes.Closes #<issue>orRefs #<issue>for issue links.
Style
- Imperative mood ("add", not "added" / "adds").
- Concise, specific, no filler — "fix bug" is forbidden; say which bug.
- English, lowercase subject.
- One blank line between header / body / footer.
- Never include AI attribution lines, signatures, co-author trailers, or trailing comments.
When uncertain
- If multiple types apply, pick the most user-visible:
feat>fix>refactor>chore. - If the scope is unclear, omit it rather than guess.
- If the body adds no signal, omit it.
- Never invent issue numbers or co-authors.
Examples
Example 1 — feature with body and change list:
:sparkles: feat(auth): add oauth2 login flow
Implement Google and GitHub providers with refresh token rotation.
- add /auth/google and /auth/github routes
- store tokens in httpOnly cookies
- update User model with provider field
Example 2 — fix with issue link:
:bug: fix(api): handle empty payload in webhook handler
Return 400 instead of crashing when webhook body is empty.
Closes #142
Example 3 — dependency upgrade, header only:
:arrow_up: build(deps): upgrade pillow to 11.0.0
Example 4 — breaking change:
:boom: feat(api)!: rename user.email to user.primaryEmail
BREAKING CHANGE: clients must use primaryEmail. The old email field
is no longer returned by /v1/users endpoints.