Comparisons

Conventional vs Custom Commits: AI Rules

Conventional Commits follow a standard format (feat:, fix:, chore:). Custom commits follow team-specific patterns. AI needs explicit rules for which format to generate, especially when Claude Code auto-commits.

6 min read·June 28, 2025

'Updated the authentication system with bcrypt hashing and...' vs 'feat(auth): add bcrypt hashing'. One rule, every commit formatted.

Conventional format, custom formats, AI agent commit behavior, commitlint enforcement, and one paragraph in CLAUDE.md

Why Commit Format Rules Matter for AI

AI coding agents generate commit messages. Claude Code: commits after completing a task with a descriptive message. Aider: auto-commits every edit with a generated message. The AI must know: which commit format the team uses. Without a commit rule: Claude Code generates natural language commits ("Updated the user authentication to use bcrypt and added password validation"). With conventional commits rule: Claude Code generates "feat(auth): add bcrypt hashing and password validation". The format determines: whether automated tools (changelogs, version bumping, release notes) can parse the commit history.

Conventional Commits: a specification for structured commit messages. Format: type(scope): description. Types: feat (new feature — bumps minor version), fix (bug fix — bumps patch), chore (maintenance), docs (documentation), style (formatting), refactor (restructuring), test (adding tests), ci (CI changes). The format is: machine-parseable. Tools: commitlint (validates format), standard-version/changesets (generates changelogs and bumps versions from commit types). Semantic versioning: derived automatically from commit types.

Custom commits: team-defined formats. Examples: "[JIRA-123] Add bcrypt hashing" (Jira ticket prefix), "auth: add bcrypt hashing" (simple prefix without conventional types), or free-form descriptions ("Add bcrypt hashing to user registration"). Custom formats: may or may not be machine-parseable. They work for: teams that do not use automated changelogs or semantic versioning. The format is: whatever the team agrees on.

Rules for Conventional Commits

Conventional commits AI rule: "Commit messages: Conventional Commits format. type(scope): description. Types: feat (new feature), fix (bug fix), chore (maintenance), docs (documentation), refactor (code restructure), test (tests), ci (CI/CD). Scope: the area of the codebase (auth, api, ui, db). Description: imperative mood, lowercase, no period. Max 72 characters for the first line. Body: optional, separated by blank line, explains WHY not WHAT. Breaking changes: append ! after type (feat!: rename user API)."

Why conventional commits rule matters for AI: Claude Code commits frequently during agentic tasks. A multi-step feature implementation: may produce 3-5 commits. Without the conventional rule: "Updated authentication", "Fixed the tests", "Added validation" — generic, not parseable. With the rule: "feat(auth): add bcrypt password hashing", "test(auth): add password validation tests", "feat(auth): add Zod input validation" — structured, versioning-ready, changelog-parseable.

Enforcement: add commitlint to the pre-commit hook. If the AI generates a non-conventional message: the commit is rejected. The AI then: regenerates with the correct format (Claude Code reads the rejection error and fixes). Double enforcement: the AI rule prevents most violations, commitlint catches the rest. Combined: every commit in the repository follows the convention, regardless of whether a human or AI created it.

  • Format: type(scope): description. Types: feat, fix, chore, docs, refactor, test, ci
  • Imperative mood, lowercase, max 72 chars: 'add bcrypt hashing' not 'Added bcrypt hashing'
  • Breaking changes: feat!: or BREAKING CHANGE: in body footer
  • Enforcement: commitlint pre-commit hook catches AI and human violations
  • Automation: changelogs, version bumping, release notes derived from commit types
💡 Structured Commits Enable Automated Releases

feat: = minor version bump. fix: = patch. BREAKING CHANGE: = major. From commit messages alone: changelogs, version numbers, and release notes generated automatically. Without conventional format: a human reads every commit and decides manually. The format enables: automation that saves hours per release.

Rules for Custom Commit Formats

Custom commit AI rule examples: Jira prefix: "Commit messages: [TICKET-NUMBER] Description. Example: [AUTH-123] Add bcrypt password hashing. Always include the Jira ticket number from the current task. If no ticket: use [NO-TICKET] prefix." Simple prefix: "Commit messages: area: description. Areas: auth, api, ui, db, infra, docs. Example: auth: add bcrypt password hashing." Free-form with guidelines: "Commit messages: imperative mood, describe the change, max 72 characters. Example: Add bcrypt password hashing to user registration."

When custom formats work: the team does not use automated changelogs (no tool needs to parse commit types), the team prefers simplicity (Jira prefix is simpler than conventional commits for Jira-heavy teams), or the existing commit history follows a custom format (changing formats mid-project creates inconsistency). Custom formats are: valid for teams that prioritize: simplicity, Jira integration, or existing conventions over automation compatibility.

When to switch to conventional: you want automated changelogs (standard-version, changesets — these parse conventional commit types), you want semantic versioning from commits (feat = minor, fix = patch, breaking = major), or you use: a monorepo with multiple packages that need independent versioning (conventional commits + changesets handle this). The switch is: adding commitlint + updating the AI rule + reformatting future commits (do not rewrite history — just use the new format going forward).

  • Jira prefix: '[AUTH-123] Add bcrypt hashing' — ties commits to tickets
  • Simple prefix: 'auth: add bcrypt hashing' — area-based without conventional types
  • Free-form: 'Add bcrypt hashing' — simplest, no parsing, no automation
  • Custom works: no automated changelogs, simplicity priority, existing convention
  • Switch to conventional: when you want automated changelogs, semver, or monorepo versioning

Special Rules for AI Agent Commits

Claude Code commit behavior: Claude Code can commit automatically after completing a task. The commit message: is generated by the AI based on the changes made. Without a format rule: the message is natural language ("Updated the authentication system with bcrypt hashing, added Zod validation for password input, and created unit tests for the new validation logic" — one long sentence). With a format rule: the AI breaks this into multiple conventional commits or one well-formatted commit.

AI commit rule for agentic mode: "When committing: use the project commit format (conventional/custom as specified above). For multi-file changes: prefer one commit per logical change (not one commit per file). If multiple features were implemented: create separate commits for each feature. Commit message: summarize the change, not list every file modified. Example: 'feat(auth): add bcrypt hashing and Zod validation' not 'Modified auth.ts, validation.ts, auth.test.ts, and schema.ts'."

The agentic commit rule prevents: one-giant-commit syndrome (Claude Code makes 15 file changes and commits them all as one massive commit with a paragraph-long message), per-file commits (15 changes = 15 tiny commits), or generic messages ("Made changes" — the AI sometimes generates unhelpfully vague messages when the task was complex). The rule tells the AI: one commit per logical change, conventional format, and summarize the WHY not list the WHAT.

  • AI default: one long natural-language sentence describing everything — not formatted
  • Rule: conventional format + one commit per logical change + summarize WHY not list files
  • Prevent: one-giant-commit (15 files in one), per-file commits (15 tiny), generic messages ('Made changes')
  • Claude Code: reads the commit format rule and generates matching messages automatically
  • Aider: auto-commits with generated messages — follows the commit rule if specified
⚠️ Prevent One-Giant-Commit Syndrome

Claude Code implements a feature touching 15 files. Without the agentic commit rule: one massive commit with a paragraph-long message. With the rule: separate commits per logical change ('feat(auth): add hashing', 'test(auth): add validation tests'). One rule prevents: unreviewa ble mega-commits.

Which Format for Your Team?

Choose conventional commits when: you want automated changelogs and release notes, you use semantic versioning (feat = minor bump, fix = patch bump), you publish npm packages (changesets + conventional commits = automated publishing), or your team values structured, machine-parseable commit history. Conventional commits are: the standard for open-source projects, npm package libraries, and teams that automate their release process.

Choose custom formats when: your team uses Jira heavily and wants ticket numbers in every commit (Jira prefix is: the most common custom format), your team finds conventional commits too rigid (the type list feels limiting), your project does not use automated changelogs (no tool parses commits), or your existing codebase has years of custom-format commits (switching creates: inconsistent history, team confusion during transition). Custom formats are: valid when they serve the team better than the standard.

Both need an AI rule: regardless of which format, the AI must know: the expected commit message format. Without the rule: the AI generates its own format (inconsistent with the team). With the rule: every AI-generated commit matches the team convention. The rule is: one paragraph in CLAUDE.md. The impact: every commit the AI generates (potentially hundreds per week with agentic coding) follows the team standard automatically.

ℹ️ One Paragraph, Every Commit Formatted

One paragraph in CLAUDE.md specifying the commit format. Impact: every AI-generated commit (potentially hundreds per week with agentic coding) follows the team standard automatically. Without: natural language paragraphs. With: structured, parseable, automation-ready commits.

Commit Format Summary

Summary of conventional vs custom commit AI rules.

  • Conventional: type(scope): description. Machine-parseable. Automates: changelogs, semver, releases
  • Custom: team-defined (Jira prefix, simple area prefix, free-form). Simpler but not automation-ready
  • AI without rule: generates natural language paragraphs as commit messages (inconsistent, not parseable)
  • AI with rule: generates formatted commits matching the team convention automatically
  • Agent commits: one per logical change, summarize WHY, not one-giant-commit or per-file
  • Enforcement: commitlint pre-commit hook catches violations from both humans and AI
  • Switch trigger: wanting automated changelogs or semantic versioning = adopt conventional
  • One paragraph in CLAUDE.md: determines the format of every AI-generated commit