Commitlint config generator — enforce Conventional Commits

Pick the commit types and scopes your team allows and set the length limits, and the tool writes a commitlint.config.js extending @commitlint/config-conventional, with the commands that install it as a Git hook.

Live demo · real result from this tool
Module format

commitlint.config.js

/** @type {import('@commitlint/types').UserConfig} */const config = {  extends: ['@commitlint/config-conventional'],  rules: {    // [level, applicable, value] — level 0 off, 1 warning, 2 error    'type-enum': [2, 'always', ['build', 'chore', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test', 'release']],    'header-max-length': [2, 'always', 100],    'body-max-line-length': [2, 'always', 100],  },}; export default config; 

Install and hook

npm install --save-dev @commitlint/cli @commitlint/config-conventional huskynpx husky initecho 'npx --no -- commitlint --edit "$1"' > .husky/commit-msg

Processed on your device — nothing is uploaded.

How to use the commitlint config generator

  1. Untick any standard type you do not want: build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test.
  2. Add extra types in Custom types (comma-separated); the default adds release.
  3. To limit scopes, list them in Allowed scopes. Tick Require a scope if every commit must name one.
  4. Set Header max length (20–200) and Body max line length (20–500), both 100 by default.
  5. Choose Module format, then copy commitlint.config.js and run the install commands shown under it.

What it does and when to use it

Conventional Commits gives each message a type and an optional scope, as in feat(api): add search endpoint. Release tools read those types to choose the next version number and build a changelog. commitlint rejects messages that break the rules before they enter history.

Set this up when a project starts publishing releases from commit history, or when messages have drifted. To write messages that pass, the Git commit message generator builds them field by field, and the changelog generator turns released changes into a CHANGELOG. The CONTRIBUTING.md generator can tell contributors which style you use.

How it works

The config extends @commitlint/config-conventional and then overrides its rules:

  • type-enum lists the ticked and custom types;
  • header-max-length and body-max-line-length use your numbers;
  • scope-enum appears only when you list scopes;
  • scope-empty: [2, 'never'] appears only when a scope is required.

The install block adds @commitlint/cli, the conventional config and husky, runs npx husky init, and writes a commit-msg hook that runs npx --no -- commitlint --edit "$1". Rule names are documented in the commitlint rules reference.

Worked examples

Defaults. All eleven standard types plus release, 100-character limits, ES module:

    'type-enum': [2, 'always', ['build', 'chore', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test', 'release']],
    'header-max-length': [2, 'always', 100],
    'body-max-line-length': [2, 'always', 100],

The file ends with export default config;.

Strict scopes for a two-app repo. Module CommonJS, scopes api, web, Require a scope ticked, header limit 72, no custom types. The rules gain 'scope-enum': [2, 'always', ['api', 'web']], and 'scope-empty': [2, 'never'],, and the file ends with module.exports = config;. A message such as fix: typo is now rejected because it has no scope.

Limits and tips

  • Other rules, such as subject case or a trailing full stop, keep the config-conventional defaults.
  • The hook command is written for a POSIX shell, so on Windows run it from Git Bash or create the file by hand.
  • Unticking every type with no custom types gives the message “Allow at least one commit type.”

Frequently asked questions

What does the 2 in each rule mean?
It is the severity. 0 turns a rule off, 1 makes it a warning, and 2 makes it an error that rejects the commit. The second value, always or never, says whether the condition must hold or must not hold.
Why add custom types such as release?
config-conventional allows only its standard list. If your release tooling or team uses another word, add it under Custom types so those commits are not rejected. Custom types are converted to lower case.
ES module or CommonJS?
Choose ES module when package.json has "type" set to "module". If you want ES module syntax without that setting, save the file as commitlint.config.mjs instead. Otherwise choose CommonJS, which ends with module.exports.
Does commitlint check commits made on GitHub's website?
No. The husky hook runs only on machines where it is installed. To check every pull request, also run commitlint in CI over the commits in the pull request.
Can I allow a scope list but keep scopes optional?
Yes. Enter the scopes and leave Require a scope unticked. A commit may then have no scope, but any scope it does have must be on the list.

Written by the ToolsRift team · Last updated

Pages are drafted with AI assistance and checked by automated tests. How we write and check pages.

Was this tool useful?

Report a problem

Start typing to search every tool.

↑ ↓ to moveEnter to openEsc to close