Home Blog Developer Experience and Pl Conventional Commits standard for engineering teams
Developer Experience and Pl May 7, 2026 10 min read

Conventional Commits standard for engineering teams

Developer Experience and Pl Enterprise Guide 2026 SCALE D2C D2C Technology Developer Experience and Pl Enterprise Guide 2026 SCALE D2C D2C Technology

Conventional Commits is a lightweight commit message specification that unlocks automated changelog generation, semantic versioning, and dramatically improved repository history navigation. Adopting it costs engineering teams roughly two weeks of habit formation and pays dividends indefinitely through better tooling, clearer history, and eliminated manual versioning work.

What Is the Conventional Commits Standard?

Conventional Commits is a specification (conventionalcommits.org) for writing structured commit messages that follow a predictable format: a type prefix, an optional scope, and a description. The types are defined: feat (new feature), fix (bug fix), docs (documentation only), refactor (code change without feature or fix), perf (performance improvement), test (adding tests), chore (maintenance tasks), and ci (CI configuration changes). Breaking changes are indicated by an exclamation mark suffix (feat!:) or a BREAKING CHANGE: footer. This structured format is designed to be human-readable and machine-parseable, enabling the automation toolchain that makes Conventional Commits valuable.

Conventional Commits Format
<type>[optional scope]: <description>

Examples:
feat(auth): add passkey authentication support
fix(api): correct rate limit calculation for burst requests
feat!: remove deprecated v1 API endpoints
100%
Automated changelog accuracy when all commits follow Conventional Commits — eliminating manual release note writing that takes 1–3 hours per release for active repositories
42%
Of the top 1,000 npm packages use Conventional Commits as their commit standard, demonstrating broad open-source ecosystem adoption
2× faster
New engineer onboarding to repository history navigation when Conventional Commits is in use — structured messages are significantly faster to scan than freeform commit messages

Commit Message Format and Types

Core types and their semantics should be understood precisely to use Conventional Commits effectively. feat is reserved for commits that add new user-visible functionality — it triggers a minor version bump in semantic versioning. fix is for commits that correct incorrect behaviour — it triggers a patch version bump. refactor is for internal code changes that neither add features nor fix bugs — it does not trigger a version bump. Incorrect type usage (marking a feature as a chore to avoid version bumping, for example) defeats the automation toolchain.

Scopes are optional but valuable for monorepos and large projects. A scope in parentheses after the type indicates which component or domain the commit affects: feat(billing): add invoice PDF generation. Scopes enable filtered changelogs by component and help code reviewers and bisect users quickly identify relevant commits. Define allowed scopes explicitly in your contributing guidelines and enforce them via commit linting to prevent scope proliferation.

Breaking changes are the most critical convention to use correctly. Any commit that changes a public API in a non-backward-compatible way must be marked with either ! after the type (feat!:) or a BREAKING CHANGE: footer in the commit body. Breaking changes trigger a major version bump in semantic versioning. Unmarked breaking changes that slip into releases without major version increments are the most common source of library consumer frustration and the most important failure mode of poorly governed Conventional Commits adoption.

TypeSemVer ImpactChangelog SectionUse When
featMinor bump (1.x.0)FeaturesNew user-facing functionality
fixPatch bump (1.0.x)Bug FixesCorrecting incorrect behaviour
feat! / BREAKING CHANGEMajor bump (x.0.0)Breaking ChangesNon-backward-compatible API changes
perfPatch bumpPerformance ImprovementsPerformance optimisations
docsNo bumpDocumentationDocumentation-only changes
refactorNo bumpCode RefactoringInternal changes, no behaviour change
test / ci / choreNo bumpExcluded by defaultTests, CI, maintenance

Tooling Ecosystem: Enforcement and Automation

Commitlint is the standard tool for enforcing Conventional Commits format in CI and as a commit-msg git hook. Configured with @commitlint/config-conventional, it validates every commit message against the specification and rejects non-conforming commits before they enter the repository. Integrating commitlint as a Husky pre-commit hook ensures all commits on developer machines are validated before reaching remote branches.

Commitizen provides an interactive CLI that guides developers through composing Conventional Commits interactively, selecting type, entering scope, and writing description through a prompted workflow. It eliminates the need for developers to memorise the specification details during the adoption period and reduces type errors from developers who are not yet fluent with the format.

semantic-release is the fully automated release pipeline that conventional commits enable. Configured for a repository, it analyses commits since the last release, determines the correct version bump, generates a changelog, creates a git tag, and publishes to npm or another registry — all automatically on CI when commits merge to the release branch. Manual versioning and changelog writing become obsolete.

Release Please (Google's alternative to semantic-release) takes a PR-based approach: it creates a release PR when new conventional commits accumulate, which teams review and merge to trigger the release. This approach provides a human review gate before release without requiring manual release steps, balancing automation with oversight.

Automated Semantic Versioning with Conventional Commits

The connection between Conventional Commits and semantic versioning is the core value proposition for library and API maintainers. When all commits follow the specification, the version bump type is computable from the commit history: any feat! or BREAKING CHANGE commit since the last release triggers a major bump; any feat commit triggers at minimum a minor bump; any fix or perf commit triggers at minimum a patch bump. No human judgment required for versioning decisions.

This automation matters most for teams releasing frequently. A team releasing weekly that previously spent 2–3 hours per release on manual version determination and changelog writing saves 100–150 hours annually — equivalent to 2–3 engineering weeks — through full release automation. For open-source maintainers releasing irregularly, the changelog generation is often more valuable than the versioning automation, providing contributors and users a readable summary of every release without manual curation.

Team Adoption Strategy and Cultural Change

Conventional Commits adoption fails when it is perceived as bureaucracy rather than tooling that makes developers' work easier. Frame the adoption around the benefits developers directly experience: no more manually writing release notes, git log that is actually readable, and the ability to bisect issues by commit type without reading every commit message.

Gradual enforcement works better than big-bang mandates. Start with tooling available but optional for 2–4 weeks, allowing early adopters to build fluency while preparing the linting infrastructure. Enable commitlint as a warning (not blocking) for the next 4 weeks. Switch to hard enforcement once 80%+ of commits are naturally conformant — typically at the 6–8 week mark.

IDE integration via VS Code's git commit UI or commit convention extensions (Conventional Commits extension for VS Code, GitLens commit templates) significantly reduces friction for developers who prefer GUI git workflows to CLI. Lower the learning curve by meeting developers in their existing tools rather than requiring CLI adoption alongside convention adoption.

Implementation Roadmap

1
Week 1
Install commitlint and Husky

Add @commitlint/cli, @commitlint/config-conventional, and husky to the project. Configure a commit-msg hook that runs commitlint. Document allowed scopes for your project. Enable as warning-only initially to collect baseline conformance data.

2
Week 2
Add Commitizen for guided commits

Install commitizen with cz-conventional-changelog adapter. Configure git cz as the team's commit command. Run a 30-minute team session demonstrating the interactive commit workflow and explaining the type semantics. Answer questions about edge cases to prevent type confusion from solidifying into bad habits.

3
Month 2
Configure automated releases

Implement semantic-release or Release Please in CI once the team has demonstrated consistent commit format compliance. Configure the changelog sections, release branch triggers, and publication targets. Run a dry-run release to validate the configuration before enabling automated publishing. Celebrate the first automated release with the team.

4
Ongoing
Enable hard enforcement and expand to all repos

Switch commitlint to blocking mode once conformance rate consistently exceeds 95%. Roll out the tooling configuration to all team repositories using a shared config package to ensure consistency. Update contributing guidelines and PR templates to reinforce the convention for external contributors on open-source repositories.

Frequently Asked Questions

Squash merging requires that the squashed commit message follow Conventional Commits format — typically the PR title, which should be set to the correct conventional format. Many teams enforce PR titles as conventional commits (using a PR title linter like semantic-pull-request) and squash merge, so the commit history reflects PR-level conventional commits rather than individual commit messages. This approach works well and produces a clean, readable history at the PR granularity. The tradeoff is loss of individual commit-level granularity in the changelog — each merged PR appears as a single entry regardless of how many commits it contained.

Monorepos use scopes to indicate which package a commit affects, enabling per-package changelog generation and versioning. Tools like Nx, Turborepo, and changesets support conventional commits with monorepo-aware release automation — generating separate changelogs and version bumps for each affected package based on the scopes of commits since the last release. The critical convention in monorepos is enforcing that scope names match package names exactly, enabling automated package identification. Lerna's conventional-changelog mode and semantic-release with monorepo plugins both support this pattern in production monorepo deployments.

Old non-conventional commits in the history are not a problem — they simply will not contribute to automated changelog generation or version determination for releases cut from the point before conventional commits adoption. Start version tracking from the commit where you enable automation, treating it as v1.0.0 regardless of the actual version history. Retroactively rewriting git history to convert old commits is not recommended — it disrupts collaborators' local histories and provides minimal practical benefit. Accept that your changelog starts from the adoption date and move forward.

Yes, though with somewhat different value emphasis. Internal applications benefit less from automated semantic versioning (which is most valuable for library consumers) but still benefit significantly from readable commit history, automated changelog generation for sprint reviews and release notes, and the cultural clarity that comes from explicit commit semantics. Teams that adopt Conventional Commits for internal applications often cite improved code review clarity (understanding the intent and impact of changes from commit messages) and faster debugging (filtering commits by type during incident investigation) as the primary benefits rather than release automation.

GitHub and GitLab both have native features that complement Conventional Commits. GitHub's Releases feature can auto-generate release notes from PR labels (a parallel approach) or can be populated by semantic-release/Release Please automation using conventional commits. GitLab's built-in changelog generation supports conventional commits format natively. For PR-based workflows, configuring branch protection to require PR titles in conventional format (via GitHub Action amannn/action-semantic-pull-request) and enforcing squash merge ensures every merge commit in the main branch follows the specification without requiring every developer's individual commits to comply — a pragmatic middle ground for teams with lower commit discipline.

The most common mistakes: using chore for everything to avoid thinking about type (produces useless changelogs); overusing feat for refactors and internal improvements (creates noisy, meaningless changelogs); forgetting to mark breaking changes (produces incorrect version bumps); ignoring scope conventions (making monorepo automation unreliable); and enforcing linting before educating the team on type semantics (produces resentment rather than understanding). The solution to most of these is education before enforcement — teams that understand why the conventions exist make better type judgments than teams applying rules they perceive as arbitrary.

Yes — Conventional Commits is a specification that is language-agnostic. The specification itself requires only a commit message format convention. Commitlint is Node.js-based, so non-JavaScript projects need either Node.js in their development environment (common in polyglot teams) or language-native alternatives. Python projects can use commitizen (Python package, different from the JS version), Go projects can use conventional-commits-linter (Go binary), and Java projects have Maven and Gradle plugins for semantic release. The specification is language-neutral; the rich tooling ecosystem is predominantly Node.js-based.

The conventional commits specification recommends atomic commits — each commit should represent a single logical change of a single type. A commit that adds a feature and fixes a bug simultaneously should ideally be two commits. In practice, teams using squash merges handle this at the PR level rather than the individual commit level — the PR title captures the primary change type, and the PR description captures the secondary changes in conventional format. For teams that cannot adopt atomic commits due to workflow constraints, using the primary change type for the mixed commit and noting secondary changes in the commit body is acceptable, accepting that minor changelog imprecision is preferable to non-adoption of the standard.

CONVENTION

Ready to Implement Conventional Commits standard for engineering team...?

Our specialist team delivers measurable ROI from Developer Experience and Pl programmes for enterprise and D2C brands.

Free Audit