Back
GitoryxGitoryx
Intermediate11 min read

Git Commit Conventions: Conventional Commits & Gitmoji

A consistent commit message format makes your Git history readable, enables automatic changelogs, and improves collaboration. This guide covers the Conventional Commits specification (feat, fix, chore, docs, refactor…), Gitmoji, and how to enforce standards in your team with hooks and tooling.

The Problem

Your team's Git history looks like: 'fix', 'fix 2', 'ok now', 'update button', 'FINAL FINAL'. Nobody can tell what changed, when, or why — and generating a changelog means reading every diff manually.

Commit conventions turn your Git history into a structured, human-readable log. They enable automatic changelog generation, clear communication during code review, and a history that makes debugging and onboarding significantly faster.

Common mistakes developers make with this:

  • Writing vague messages like 'fix', 'update', 'wip'
  • Mixing multiple concerns in one commit without a clear type
  • Not following a convention consistently — some commits use it, others don't
  • Using emojis without a system, so they add noise instead of signal

Gitoryx: Gitoryx displays commit types as colored badges in the commit graph — so you can immediately see which commits are features, fixes, or chores without reading each message.

What is Commit Conventions: Conventional Commits & Gitmoji?

A commit convention is a structured format for writing commit messages. The most widely adopted is Conventional Commits: <type>(<scope>): <description>. Gitmoji extends this by prefixing each commit with an emoji that visually encodes the type.

Step-by-Step Guide

1

Understand the Conventional Commits format

The format is: <type>(<optional scope>): <short description>. The type is mandatory and must be one of a predefined set.

bash
feat(auth): add JWT refresh token support
fix(cart): correct item count when quantity is zero
chore(deps): update lodash to 4.17.21
docs(readme): add installation instructions
refactor(api): extract user validation to separate module
test(auth): add unit tests for token expiration
ci(github): add automated deployment workflow
style(button): fix indentation in Button component

The scope is optional but highly recommended for large codebases. It tells reviewers exactly where the change lives.

2

Learn the standard commit types — complete reference

Each type has a precise meaning. Using them consistently makes git log immediately informative and enables tooling like automatic changelogs. Here is the full reference table:

bash
feat     → A new feature visible to users (triggers MINOR in semver)
              Examples: feat(auth): add Google OAuth login
                        feat(api): expose /v2/users endpoint

fix      → A bug fix that corrects existing behavior (triggers PATCH in semver)
              Examples: fix(cart): correct item count when quantity is zero
                        fix(login): prevent null crash on empty email

chore    → Maintenance tasks that do NOT affect production code or public API
              Examples: chore(deps): update lodash to 4.17.21
                        chore(build): upgrade webpack config
                        chore(.gitignore): add .DS_Store

docs     → Documentation changes only — no code logic
              Examples: docs(readme): add installation steps
                        docs(api): document /users query params

style    → Formatting, whitespace, semicolons — zero logic change
              Examples: style(button): apply Prettier formatting

refactor → Code restructuring without adding features or fixing bugs
              Examples: refactor(auth): extract token logic to service layer

test     → Adding or updating automated tests
              Examples: test(cart): add unit tests for discount calculation

ci       → Changes to CI/CD pipeline configuration
              Examples: ci(github): add automated deployment on tag push

perf     → Performance improvements
              Examples: perf(images): lazy-load below-the-fold thumbnails

revert   → Reverts a previous commit
              Examples: revert: feat(auth): add Google OAuth login

When in doubt between chore and refactor: if a user or public API is unaffected and it's housekeeping (deps, tooling, config), use chore. If it's restructuring internal code logic, use refactor.

3

What does chore mean in a git commit?

chore is for internal maintenance tasks that keep the project running but have no impact on the public API or end-user behavior. If a user or a consumer of your package would never notice the change, it's a chore.

bash
# Dependency updates — the most common chore
chore(deps): upgrade eslint to v9
chore(deps): bump react from 18.2 to 18.3

# Build system and tooling
chore(build): migrate from CRA to Vite
chore(webpack): enable tree-shaking for prod builds

# Repository housekeeping
chore(.gitignore): add .DS_Store and .env.local
chore(scripts): add pre-commit formatting hook

# Removing dead code / cleanup (no logic change)
chore: remove unused legacy auth module
chore: delete commented-out console.log calls

A good litmus test: if you would need to mention this change in a user-facing CHANGELOG, it's probably not a chore. If it's invisible to users, it is.

4

Mark breaking changes

Add BREAKING CHANGE: in the commit body, or add ! after the type, to signal an API-breaking change. This triggers a MAJOR version bump in semantic versioning.

bash
feat(api)!: remove deprecated /v1/users endpoint

BREAKING CHANGE: The /v1/users endpoint has been removed.
Use /v2/users instead.
See this workflow in Gitoryx — Gitoryx screenshot

See this workflow in Gitoryx. Built-in Gitmoji picker — browse and insert any emoji from the commit panel in one click

Free download
5

Use Gitmoji for visual commit history

Gitmoji maps emojis to commit types. Every emoji has a specific meaning, making the log instantly scannable.

bash
✨ feat: add dark mode toggle
🐛 fix: correct off-by-one error in pagination
♻️  refactor: extract auth logic to service layer
📝 docs: update API reference
🚀 ci: deploy to production on tag push
⚡️ perf: cache user preferences in localStorage
🔒 fix: sanitize user input to prevent XSS
🎨 style: apply Prettier formatting
🗑️  chore: remove unused imports
✅ test: add integration tests for checkout flow

You don't have to pick between Conventional Commits and Gitmoji — many teams use both: ✨ feat(auth): add login form

6

Enforce conventions with a commit-msg hook

Use commitlint + Husky to automatically reject commits that don't follow the convention.

bash
# Install commitlint
npm install --save-dev @commitlint/cli @commitlint/config-conventional

# Create config
echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js

# Add Husky hook
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'
7

Generate a changelog automatically

With Conventional Commits in place, tools like standard-version or release-please can generate a full changelog and bump the version automatically.

bash
# Install standard-version
npm install --save-dev standard-version

# Add to package.json scripts:
# "release": "standard-version"

npm run release
# → bumps version in package.json
# → generates/updates CHANGELOG.md
# → creates a git tag

Common Mistakes to Avoid

Inconsistent adoption

Half the team uses conventions, half doesn't. The log becomes a mix of structured and unstructured messages.

Fix: Enforce it automatically with commitlint. A hook that rejects non-conforming messages eliminates the inconsistency.

Using `feat` for everything

Some developers use feat for bug fixes, refactors, and documentation changes because it feels more exciting.

Fix: The type must match the intent. Misusing types breaks automated changelog generation and makes the log misleading.

Using emojis without a standard

Random emojis picked on a whim add visual noise instead of useful signal.

Fix: Adopt the official Gitmoji list (gitmoji.dev) so every emoji has a consistent, shared meaning.

Gitoryx — visual Git client for macOS & Windows
GitoryxGitoryx — macOS & Windows

Write better commit messages in Gitoryx

  • Built-in Gitmoji picker — browse and insert any emoji from the commit panel in one click
  • Conventional Commits type selector directly in the commit message input
  • Commit history shows Gitmoji emojis rendered inline next to messages
  • Integrate commitlint via a pre-commit hook — Gitoryx surfaces hook errors inline
Download Gitoryx — FreemacOS · Windows · No subscription

Frequently Asked Questions

What does chore mean in a git commit?

chore is a commit type for maintenance tasks that do not affect production code or the public API. Typical chores include updating dependencies (chore(deps): bump lodash), adjusting build tooling (chore(build): migrate to Vite), and repository housekeeping like updating .gitignore. If end users would never notice the change, it's a chore.

What is chore in git?

In Git commit conventions (Conventional Commits), chore is the type label for internal housekeeping tasks — things like dependency upgrades, build system changes, and configuration updates that have no user-visible impact. It is one of the ten standard commit types alongside feat, fix, docs, style, refactor, test, ci, perf, and revert.

What is the difference between chore and refactor in git commits?

Use chore for tasks that keep the project healthy but don't change any code logic — like updating a dependency or cleaning up .gitignore. Use refactor when you restructure or rewrite internal code without changing its external behavior. A chore is housekeeping; a refactor is code-level restructuring.

What is feat in a git commit message?

feat stands for 'feature'. It marks a commit that adds new functionality visible to users or API consumers. In semantic versioning, a feat commit triggers a MINOR version bump (e.g., 1.2.0 → 1.3.0). Example: feat(auth): add Google OAuth login.

What is the Conventional Commits specification?

Conventional Commits is a lightweight specification for commit message format: <type>(<scope>): <description>. Common types are feat, fix, chore, docs, refactor, test. It enables automated changelog generation and semantic versioning.

What are all the git commit message types?

The standard Conventional Commits types are: feat (new feature), fix (bug fix), chore (maintenance), docs (documentation), style (formatting), refactor (code restructure), test (tests), ci (CI/CD changes), perf (performance), revert (reverts a commit). Teams can also define custom types.

What is Gitmoji?

Gitmoji is a convention that maps specific emojis to commit intents. For example: ✨ for new features, 🐛 for bug fixes, ♻️ for refactors. It makes the commit log visually scannable. See the full list at gitmoji.dev.

Should I use Conventional Commits or Gitmoji?

Both work well, and they can be combined: ✨ feat(auth): add login form. Conventional Commits is better for tooling (automated changelogs, semantic release). Gitmoji adds a visual layer on top. Pick one or both — consistency matters more than which system you choose.

How do I enforce commit conventions in my team?

Use commitlint with a Husky commit-msg hook. It automatically rejects commits that don't match the configured format and shows an error message explaining the correct format.

See it in action with Gitoryx

Everything in this tutorial is faster and clearer with a visual Git client. Gitoryx is free, runs natively on macOS and Windows, and built for developers who want to move fast without breaking things.