PR title & commit message linter

Paste a PR title or commit messages, get instant Conventional Commits validation: type, scope, length, mood, punctuation. Free, runs entirely in your browser.

Checks Conventional Commits format (type, scope, subject), header length (50/72), trailing punctuation, and imperative mood. Runs entirely in your browser.

feat(api): Added rate limiting to the webhook endpoint.
  • Drop the trailing punctuation in the subject
  • Conventional style: start the subject lowercase ("add", not "Add")
  • Use imperative mood: "added" → try "add" (complete the sentence "this commit will …")
  • 55 chars — under 50 is ideal, 72 is the hard ceiling

What is PR linting?

PR linting validates the metadata of a pull request, mainly its title and commit messages, against a convention before merge. The dominant convention is Conventional Commits: type(scope): subject, where type is one of feat, fix, docs, refactor, perf, test, build, ci, chore, or revert.

Why teams enforce it:

  • Squash merges make the PR title the commit message. If you squash (most teams do), the PR title becomes the permanent history line. A linted title means a readable git log.
  • Automated changelogs and releases. semantic-release and release-please derive version bumps from types: fix → patch, feat → minor, feat! or BREAKING CHANGE → major. One mistyped title means a wrong version number.
  • Scannable history. fix(auth): reject expired session tokens tells the next engineer what happened without opening the diff.

How do I enforce PR lint in CI?

Two standard setups:

  1. PR title only (squash-merge teams): the semantic-pull-request GitHub Action lints the title on every PR event. Make it a required check in branch protection and unconventional titles cannot merge.
  2. Every commit (merge-commit teams): run commitlint with @commitlint/config-conventional in CI, plus a local commit-msg hook via Husky so authors get feedback before pushing.

Either way, pair the gate with this page's free checker so contributors can fix titles before CI complains.

The rules this linter applies

  • Format: type(scope)!: subject with a known lowercase type; scope optional; ! marks breaking changes.
  • Length: 50 characters ideal, 72 hard ceiling. GitHub truncates around 72 in most views.
  • Imperative mood: "add rate limiting", not "added rate limiting". Complete the sentence "this commit will …".
  • No trailing period. It's a header, not a sentence.

Title hygiene is one slice of PR quality. The rest is structure and review: a clear description (PR description generator), a sane size (PR size calculator), and an automated first review pass. Diffwise handles that last layer with 40+ specialist agents on every PR and a Check Run that can block merge on critical findings, the same enforcement pattern as your lint gate, applied to the code itself.

Frequently asked questions

What is the Conventional Commits format?

type(scope): subject — for example "feat(auth): add session revocation". Types signal intent: feat (new behavior), fix (bug fix), refactor, docs, test, perf, build, ci, chore, revert. An exclamation mark (feat!:) or a BREAKING CHANGE footer marks breaking changes.

Why must commit messages be imperative?

Convention from git itself: a commit message completes the sentence "if applied, this commit will …". "add rate limiting" reads correctly; "added rate limiting" doesn't. Consistency makes git log scannable.

Why does the 72-character limit matter?

git log, GitHub, and most tooling truncate or wrap commit headers around 72 characters. 50 is the conventional soft target so the header stays readable in one line everywhere.

Does the PR title matter if commits are squashed?

It matters more: with squash merge, the PR title becomes the single commit message that survives in history, and release tooling reads version bumps from it.

Is this linter free?

Yes. Free, no signup, fully client-side — nothing you type leaves your browser.