Here we go. It’s my second article.
So, before going deep into actual development stuff, I thought I’d write about a good developer practice. Something that improves productivity and teamwork — something that’s equally important as coding and engineering.
A good commit history.
The first time I found out about proper commit styles was from one of my friends. He wrote an article about common commit styles. You can read it here.
He covered multiple styles in that article.
In this one, I’m only going into my favorite style — Conventional Commits.
You can find the official Conventional Commits specification here. It is heavily inspired by the Angular Commit Guidelines.
Now, let’s start.
Why Even Use a Commit Style?
When you get into development, you are definitely going to use a version control system like Git.
And when you look at the commit history, you should be able to easily determine:
- What changed
- Where it changed
- When it changed
- And sometimes even why it changed
Even if you come back to your codebase after a long time, everything should still make sense.
And when you’re working in a team, this becomes even more important.
Yes, you know what you did.
But your teammates don’t live inside your brain.
They should also be able to understand what happened just by reading the commit history.
When everyone uses some kind of standard method, the commit history looks clean and consistent. Even a new team member can understand the project structure much faster.
So whatever commit style you choose — Conventional Commits or something else — just be consistent.
Now let’s see how this actually works.
Base Structure
This is the structure a Conventional Commit follows. Some parts are optional.
<type>(<scope>): <description>
<blank line>
<body>
<blank line>
<footer(s)>
Now let’s break it down simply.
- type – The kind of change you are making (feature, fix, docs, etc.)
- scope (optional) – The part of the codebase affected
- description – A short summary of the change
- body (optional) – A more detailed explanation
- footer (optional) – Extra information like breaking changes, issue references, reviewers (can have multiple)
A Full Example
Here’s a full commit message using all parts:
feat(auth): add JWT token validation
Implement token verification middleware to protect private routes.
Reject requests with expired or malformed tokens.
Closes: #42
Reviewed-by: Nadeeshan
Simple. Structured. Easy to understand.
Most Commonly Used Types
Here are the most commonly used types and what they mean:
- chore – Routine tasks (dependency updates, config changes, etc.)
- feat – A new feature
- fix – A bug fix
- style – Code style changes (formatting, spacing, no logic change)
- test – Adding or updating tests
- docs – Documentation changes
- build – Changes that affect the build system or dependencies
- ci – CI/CD configuration changes
- perf – Performance improvements
- refactor – Code changes that neither fix a bug nor add a feature
- revert – Reverts a previous commit
Once you get used to these types, writing commits becomes second nature.
Now, Let’s Look at Some Examples
The most basic commit message (without optional parts) looks like this:
feat: add dark mode toggle
docs: update installation instructions
refactor(api): simplify user validation logic
Here’s one with a body:
fix: resolve duplicate email validation bug
Add unique constraint check before inserting user into database.
Prevents application crash when duplicate email is submitted.
And one with body + footer:
perf: improve image loading speed
Implement lazy loading for large images on dashboard page.
Reduces initial load time significantly.
Closes: #108
See? That’s actually very simple.
When Breaking Changes Are Present
If your change introduces something that breaks existing functionality, you can:
- Add
!after the type - Or include
BREAKING CHANGE:in the footer
Both are valid.
Examples:
Using !:
feat!: migrate authentication system to OAuth2
With scope:
refactor(api)!: change response structure of user endpoint
Using footer:
feat: add role-based access control
Introduce role field to user model and enforce role checks in middleware.
BREAKING CHANGE: existing user records must be updated with a role field.
Another example using both ! and a footer:
chore!: remove legacy config loader
BREAKING CHANGE: old config.json format is no longer supported.
Breaking changes usually mean a major version bump if you're following semantic versioning.
So, Why Conventional Commits?
This is probably one of the most widely used commit styles in the developer community.
It’s:
- Well structured
- Easy to read
- Easy to maintain
- Easy to automate
And if you follow this style, you unlock more advanced things later.
Since this style correlates with Semantic Versioning (MAJOR.MINOR.PATCH):
-
fix→ PATCH -
feat→ MINOR -
BREAKING CHANGE→ MAJOR
This means you can:
- Automatically generate changelogs
- Automatically bump versions
- Integrate tools like commitlint
- Build CI/CD workflows around commit messages
Now your commit history isn’t just text.
It becomes data.
And that’s powerful.
More Common Commit Message Guidelines You Should Follow
Even with Conventional Commits, follow these general rules:
- Use present tense, imperative form
- ✓
add login validation - ✗
added login validation
- ✓
- Keep each commit focused on a single concern
- Use lowercase for the type and description
- Avoid ending the subject line with a period
- Limit the subject line to about 50 characters
- Separate the subject and body, and also the body and footer, with a blank line
- Mention issues, tasks, or reviews in the footer
Again, this is a convention.
The most important thing is consistency with your team. So, follow the style guide that everyone else uses.
Final Thoughts
I have seen people use commit messages where the history looks like this:
updated something
fix stuff
final
final_final
real_final_this_time
And that is not very helpful.
If you’re just starting out, I highly recommend trying this style in your next project.
It forces you to think:
"What exactly am I changing?"
And that small habit alone makes you a better developer.
Thank You
So thank you for reading yet another not-so-long article.
I hope you learned something from this.
Let me know your take on this style, or point out if I’ve stated something wrong, in the comments below.
So, my fellow developers — until next time.
Go beyond plus ultra.
Top comments (0)