Skip to content
Developer Template5 columns · 7 sample rows· Updated

Conventional Commits & Semantic Releases Markdown Table Template

This table is the contract between the people who write commits and the tooling that turns those commits into version numbers and release notes. Contributors skim it once in CONTRIBUTING.md and then again every time commitlint rejects a message; maintainers come back to it when they configure semantic-release, release-please, or conventional-changelog and need to know which prefixes cut a release and which ones are silently ignored.

Edit This Template

Edit cells, add rows, or sort — the Markdown updates live
Row
1
feat
MINOR
feat(editor): add multi-cursor keyboard shortcuts
2
fix
PATCH
fix(parser): escape literal pipes inside inline code
3
<type>! / BREAKING CHANGE: footer
MAJOR
feat(api)!: remove deprecated v1 endpoint
4
docs
docs(readme): add docker port configuration table
5
perf
PATCH
perf(engine): optimize AST matrix transposition
6
refactor
refactor(utils): extract delimiter sniffing logic
7
chore
chore(deps): bump next from 15.0 to 15.1
Output
| Commit Type                           | Description / Purpose                                       | SemVer Impact | Changelog Section        | Commit Message Example                                 |
| :------------------------------------ | :---------------------------------------------------------- | :-----------: | :----------------------- | :----------------------------------------------------- |
| `feat`                                | A brand new user-facing feature or capability               |   **MINOR**   | Features                 | `feat(editor): add multi-cursor keyboard shortcuts`    |
| `fix`                                 | A bugfix resolving an existing issue                        |   **PATCH**   | Bug Fixes                | `fix(parser): escape literal pipes inside inline code` |
| `<type>!` / `BREAKING CHANGE:` footer | Any change introducing a breaking API modification          |   **MAJOR**   | ⚠️ Breaking Changes      | `feat(api)!: remove deprecated v1 endpoint`            |
| `docs`                                | Documentation only changes (README, guides, comments)       |     None      | Hidden                   | `docs(readme): add docker port configuration table`    |
| `perf`                                | Code change improving algorithmic performance or latency    |   **PATCH**   | Performance Improvements | `perf(engine): optimize AST matrix transposition`      |
| `refactor`                            | Code restructuring without changing behavior or fixing bugs |     None      | Hidden                   | `refactor(utils): extract delimiter sniffing logic`    |
| `chore`                               | Build process, package updates, or tooling configuration    |     None      | Hidden                   | `chore(deps): bump next from 15.0 to 15.1`             |
7 rows × 5 columns
Rendered Preview
Commit TypeDescription / PurposeSemVer ImpactChangelog SectionCommit Message Example
featA brand new user-facing feature or capabilityMINORFeaturesfeat(editor): add multi-cursor keyboard shortcuts
fixA bugfix resolving an existing issuePATCHBug Fixesfix(parser): escape literal pipes inside inline code
<type>! / BREAKING CHANGE: footerAny change introducing a breaking API modificationMAJOR⚠️ Breaking Changesfeat(api)!: remove deprecated v1 endpoint
docsDocumentation only changes (README, guides, comments)NoneHiddendocs(readme): add docker port configuration table
perfCode change improving algorithmic performance or latencyPATCHPerformance Improvementsperf(engine): optimize AST matrix transposition
refactorCode restructuring without changing behavior or fixing bugsNoneHiddenrefactor(utils): extract delimiter sniffing logic
choreBuild process, package updates, or tooling configurationNoneHiddenchore(deps): bump next from 15.0 to 15.1

When to Use This Table

Keep the specification and your project’s policy apart. Conventional Commits 1.0.0 gives meaning to only three things: fix maps to a SemVer PATCH, feat maps to MINOR, and a breaking change, marked with ! before the colon or with a BREAKING CHANGE: footer, maps to MAJOR whatever the type. Every other prefix (docs, perf, chore, ci, build, style, test, refactor, revert) is convention inherited mostly from the Angular commit guidelines, and whether it triggers a release is decided by your release tool, not by the spec.

A good version of this table is short enough to memorize, lists only the types your commitlint config actually accepts, and shows a real message for each one. A weak version copies a list of types from a blog post, claims perf always means PATCH without saying which tool decided that, and glosses over the breaking-change syntax, which is the single rule that, when misapplied, ships an API break as a patch release.

What Goes in Each Column

ColumnAlignmentWhat to put here
Commit Typeleft :---The bare type token in backticks and lowercase, exactly as the type-enum rule in your commitlint config spells it. The spec treats types as case-insensitive, but one casing keeps the column scannable. Show the breaking form as type! rather than inventing a separate type: the ! modifier works on any type, not only feat and fix.
Description / Purposeleft :---One line answering “when do I pick this type?” from the contributor’s side. Spell out the borderlines with neighbouring types, such as refactor versus perf or chore versus build, because those are the cases authors and reviewers end up debating in PR comments.
SemVer Impactcenter :---:MAJOR, MINOR, PATCH, or None, centered so the column reads as a quick lookup. Only feat, fix, and breaking changes get their impact from the spec itself. For everything else, write what your release tool is configured to do (semantic-release’s default rules also bump PATCH for perf and for reverts) and note which tool that is.
Changelog Sectionleft :---The heading this type produces in generated release notes: Features, Bug Fixes, Performance Improvements, and so on. Copy the exact strings your changelog preset emits so readers can match the table against a real CHANGELOG.md, and write Hidden for types the preset leaves out; conventional-changelog presets hide types such as chore, style, and test unless configured otherwise.
Commit Message Exampleleft :---A complete header in backticks following type(scope): description, written in the imperative mood with no trailing period. Use scopes that really exist in the repository (package or module names) so the example doubles as documentation of the scope list. @commitlint/config-conventional caps the header at 100 characters through header-max-length.

How to Fill It In

  1. 1Start from the linter, not the spec. Open commitlint.config.js (or the commitlint key in package.json) and copy its type-enum list. If you extend @commitlint/config-conventional, the allowed types are build, chore, ci, docs, feat, fix, perf, refactor, revert, style, and test.
  2. 2Fill SemVer Impact from your release tool’s configuration: releaseRules for semantic-release’s commit analyzer, or changelog-sections and the versioning settings in release-please-config.json. Then confirm with a dry run (npx semantic-release --dry-run) on a scratch branch that contains one commit of each type.
  3. 3Generate a changelog locally and copy the headings it actually prints into Changelog Section. If a type does not appear in the output, mark it Hidden instead of guessing a heading.
  4. 4Take example messages from your own git log --oneline where you can. Real history shows newcomers which scopes are in use and how specific a good description is; edit only to fix typos.
  5. 5Test the breaking-change row last, in both forms: a header such as feat(api)!: drop v1 routes and a footer line beginning with BREAKING CHANGE:. The spec requires that footer token in uppercase (or the synonym BREAKING-CHANGE), so a lowercase breaking change: footer will not be detected by compliant parsers.

Ready-to-Paste Variations

Compact README version

Four rows that cover what the spec actually defines. Good for a README badge section or the top of CONTRIBUTING.md, with a link to the full list.

| Prefix | Use it for | Release |
| :--- | :--- | :---: |
| `fix:` | A bug fix users can notice | PATCH |
| `feat:` | New user-facing capability | MINOR |
| `<type>!:` or `BREAKING CHANGE:` footer | Anything that breaks existing callers | MAJOR |
| `docs:` `chore:` `ci:` `test:` … | Everything else | None |

Full config-conventional type list

All eleven types accepted by @commitlint/config-conventional, with the default semantic-release behaviour and whether the conventionalcommits changelog preset shows them by default.

| Type | Purpose | Default release | In changelog |
| :--- | :--- | :---: | :---: |
| `feat` | New feature | MINOR | Features |
| `fix` | Bug fix | PATCH | Bug Fixes |
| `perf` | Performance improvement, no API change | PATCH | Performance Improvements |
| `revert` | Reverts an earlier commit | PATCH | Reverts |
| `refactor` | Restructure code without changing behaviour | None | Hidden |
| `docs` | Documentation only | None | Hidden |
| `style` | Formatting, whitespace, semicolons | None | Hidden |
| `test` | Add or fix tests | None | Hidden |
| `build` | Build system or external dependencies | None | Hidden |
| `ci` | CI configuration and scripts | None | Hidden |
| `chore` | Maintenance that touches neither src nor tests | None | Hidden |

Breaking-change syntax reference

The ways a commit can signal a major bump. Paste this next to the main table, because it is the part contributors get wrong most often.

| Form | Where it goes | Example | Detected as breaking |
| :--- | :--- | :--- | :---: |
| `!` after type | Header | `refactor(auth)!: require PKCE for all clients` | Yes |
| `!` after scope | Header | `feat(api)!: remove /v1/tables` | Yes |
| `BREAKING CHANGE:` footer | Last paragraph of the body | `BREAKING CHANGE: Node 18 is no longer supported` | Yes |
| `BREAKING-CHANGE:` footer | Last paragraph of the body | `BREAKING-CHANGE: config key renamed to outDir` | Yes |
| Prose in body only | Body | `This removes the old flag.` | No |

Common Mistakes

  • Believing only feat! and fix! can be breaking.

    Any type takes the ! modifier. A refactor! that renames a public export or a build! that drops a supported runtime is a MAJOR change, and the table should say so in its breaking row.

  • Describing the break in the commit body without the footer token or !.

    Tools only look for the ! marker or a BREAKING CHANGE: footer. Prose such as “this removes the old flag” is invisible to them, so the release ships as a minor or patch version.

  • Filing runtime dependency upgrades under chore(deps) when they change behaviour users see.

    Use fix(deps) for an upgrade that fixes a user-facing bug, and keep chore or build for upgrades with no runtime effect. Dependabot and Renovate both let you set the commit prefix per dependency type.

  • Linting individual commits but squash-merging with an unchecked PR title.

    With squash merges, the squash commit’s header (usually the PR title) is the only thing the release tool reads. Add a CI check that lints the PR title against the same rules.

Browse all 50 templates
FAQ

Conventional Commits & Semantic Releases: Frequently Asked Questions

Do I have to use types other than feat and fix?

No. The 1.0.0 spec only requires feat and fix to carry their meaning and allows any other type. Extra types are useful for filtering history and hiding noise from release notes, but they are a team convention you can trim.

Can I use both ! and a BREAKING CHANGE footer on one commit?

Yes. The ! makes the break visible in one-line logs, and the footer explains what changed and how to migrate. When ! is present the spec lets you omit the footer, in which case the description itself must describe the break.

What happens to breaking changes before version 1.0.0?

Under SemVer, anything may change in 0.y.z, and tools differ here. release-please has a bump-minor-pre-major option that turns breaking changes into minor bumps while the major version is zero; check your tool’s setting and state the policy under the table.

How should a revert commit look?

The spec suggests the revert type with a footer that references the reverted commit SHAs, for example Refs: 676104e, a215868. semantic-release’s default rules treat a revert as a PATCH release; other tools may ignore it unless configured.

Is the scope in parentheses required?

No, it is optional. When used, the spec says it must be a noun describing a section of the codebase. Many teams restrict scopes with commitlint’s scope-enum rule so release notes group cleanly by package.