How to use the commitlint config generator
- Untick any standard type you do not want: build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test.
- Add extra types in Custom types (comma-separated); the default adds
release. - To limit scopes, list them in Allowed scopes. Tick Require a scope if every commit must name one.
- Set Header max length (20–200) and Body max line length (20–500), both 100 by default.
- Choose Module format, then copy
commitlint.config.jsand 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-enumlists the ticked and custom types;header-max-lengthandbody-max-line-lengthuse your numbers;scope-enumappears 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?
Why add custom types such as release?
ES module or CommonJS?
Does commitlint check commits made on GitHub's website?
Can I allow a scope list but keep scopes optional?
How do we know nothing is uploaded? Test it yourself on the privacy proof page.