How to use
- Copy the installation command and review the source package before installing it in your own agent environment.
- Check the source document for required tools, credentials and supported hosts.
- Describe your input and desired deliverable; review the output against the source material.
npx skills add https://github.com/TerminalSkills/skills --skill commitlintBefore you start
- Installation does not include a model subscription, API allowance or permission to access your files.
- Repository stars and installation counts describe activity, not an independent quality or security test.
Rendered from the source repository. Headings, examples, code, tables, links, and referenced images are preserved.
commitlint
Overview
commitlint (@commitlint/cli, v21 at the time of writing) lints a commit message against a rule set; the usual rule set is @commitlint/config-conventional, which enforces type(scope?): subject. It requires Node.js 22.12 or newer. It runs in a Git commit-msg hook (typically via husky) and in CI. Valid messages let tools such as semantic-release, release-please, changesets or conventional-changelog derive version bumps and changelogs.
Instructions
Step 1: Install and add the hook (husky v9)
npm install -D @commitlint/cli @commitlint/config-conventional husky
npx husky init
echo 'npx --no -- commitlint --edit "$1"' > .husky/commit-msgnpx husky init also creates .husky/pre-commit containing npm test, which makes every commit fail in a project without tests. Edit or empty that file if you do not want it.
Step 2: Configure
Create commitlint.config.mjs (or commitlint.config.js with "type": "module", .cjs, .ts, .commitlintrc.*, or a commitlint key in package.json).
// commitlint.config.mjs
export default {
extends: ['@commitlint/config-conventional'],
rules: {
// [severity, applicable, value]; severity 0 off, 1 warning, 2 error
'scope-enum': [2, 'always', ['auth', 'api', 'billing', 'ui', 'deps']],
'scope-case': [2, 'always', 'kebab-case'],
'header-max-length': [2, 'always', 72],
},
}The default type-enum is build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test. If you override type-enum, repeat the types you still want, including revert. Default config-conventional limits headers and body/footer lines to 100 characters and forbids sentence-case subjects and trailing periods.
Step 3: Try it
echo "updated stuff" | npx commitlint # exit 1: subject and type may not be empty
echo "feat(auth): add Google OAuth login" | npx commitlint # exit 0
git commit -m "fix(api): handle null response from /users" # hook runs commitlintStep 4: Lint in CI
# .github/workflows/commitlint.yml
name: commitlint
on: [pull_request]
jobs:
commitlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verboseOther useful forms: npx commitlint --last (latest commit), --from origin/main (everything since main), --config path for a non-default config. If you squash-merge, lint the PR title instead of the individual commits.
Examples
Example 1: Add commit linting to an existing repo
User request: "Make everyone on the team use conventional commits."
Run Step 1 and Step 2, empty .husky/pre-commit if the repo has no npm test, and commit commitlint.config.mjs and .husky/. Then git commit -m "updated stuff" is rejected with type may not be empty [type-empty], and git commit -m "feat(billing): add annual plan" succeeds. Add a prepare script ("prepare": "husky", which husky init sets) so teammates get hooks after npm install.
Example 2: Restrict scopes to the monorepo packages
User request: "Only allow scopes that match our package names."
Set 'scope-enum': [2, 'always', ['web', 'api', 'worker']]. Then echo "feat(mobile): add push" | npx commitlint exits 1 with scope must be one of [web, api, worker] [scope-enum], while fix(api): retry on 503 passes.
Guidelines
- Hooks can be bypassed with
git commit --no-verify; keep the CI check as the enforcement point. - Merge and revert commits generated by Git are ignored by default; do not disable that.
subject-max-lengthdoes not exist in config-conventional by default; the header limit isheader-max-length(100).- Breaking changes use
feat!:or aBREAKING CHANGE:footer and map to a major version;featmaps to minor,fixto patch. - commitlint only lints messages; it does not generate changelogs. Pair it with a release tool.
- On older Node versions install an older commitlint major; v21 needs Node 22.12 or newer.

