Six months of commit messages that say “fix”, “wip” and “changes” tell the next developer nothing - and on a small team the next developer is usually you. Conventional Commits add one prefix to every message and turn the log into something you can actually read.
The whole format#
type(scope): short summary
The types that earn their keep on a Laravel app:
feat- new behaviour (feat(billing): add invoice PDF download)fix- a bug (fix(queue): stop retrying permanently failed jobs)refactor- same behaviour, different codetest- tests onlychore- dependencies, config, toolingdocs- the README and friends
The scope is optional but cheap: one word naming the part of the app (billing, queue, auth). The summary stays imperative and under about 70 characters.
What it buys#
git log --oneline becomes a changelog draft: everything user-visible is a feat or fix, everything else filters out. That is exactly the input the tags-to-changelog habit needs, and it makes releases a paste-and-edit job instead of an archaeology dig. Review gets faster too - a refactor prefix sets expectations before the diff loads, and nobody hunts for behaviour changes in a commit that announced there are none.
Breaking changes get a ! (feat(api)!: drop v1 endpoints) or a BREAKING CHANGE: footer, so they are impossible to miss at release time.
Adopt it without a fight#
The failure mode is process, not spelling: a team that gets a 12-type spec and a CI gate on day one starts writing chore: stuff to make the check pass. Start smaller:
- Five or six types, written in the README or pull request template.
- Scope optional, body only when the why is not obvious from the diff.
- No CI enforcement at first. Squash-merge pull requests and write the conventional message on the squash commit - main stays clean even when the branch’s own commits are messy.
If it still feels like overhead after a month, drop it. A convention the team half-follows is worse than none, because it teaches people the log cannot be trusted. The bar is not a perfect history; it is a git log you can skim before a release and believe.
Share this post
Keep reading
Shipping a Laravel App From Git
Keep deploys boring: build from a tagged commit, migrate, cache.
A First CI Pipeline for a Laravel Project
Install, lint, test, build - four jobs that run on every pull request and turn 'works on my machine' into a check everyone can see.
A Staging Environment Worth Having
Staging only catches what it shares with production. Same deploy path, same services, sanitized data - and a clear rule for what it is for.