Understanding Semantic Versioning: When to Bump Major, Minor, or Patch
If you’re building software and using version numbers like 1.0.5, you’ve probably come across the concept of Semantic Versioning (SemVer). But when exactly should you increase the 1, the 0, or the 5?
It’s a simple system on the surface, but many developers still hesitate when deciding whether a change is worth a patch, a minor bump, or a major release. Here’s a clear breakdown of what each number really means — and how to version your project with confidence.
📘 What Is Semantic Versioning?
Semantic Versioning uses three numbers, separated by dots:
MAJOR.MINOR.PATCH
Each number communicates something specific about the changes made in a release.
🔍 What Do the Numbers Mean?
| Section | Example | Meaning |
|---|---|---|
MAJOR | 1.x.x | Breaking changes. Incompatible API updates. |
MINOR | x.1.x | New features. Backward-compatible. |
PATCH | x.x.1 | Bug fixes only. Backward-compatible. |
🔺 When to Bump MAJOR (e.g. 1.0.0 → 2.0.0)
Increase the MAJOR version when you make changes that break backward compatibility.
✅ Examples:
- Removing or renaming existing functions
- Changing return types or parameter orders
- Changing behavior in a way that might break consumer apps
- export function getUser()
+ export function fetchUser() // incompatible change
➡️ New version: 2.0.0
🔹 When to Bump MINOR (e.g. 1.0.5 → 1.1.0)
Increase the MINOR version when you add new features, but they are fully backward-compatible.
✅ Examples:
- Adding a new function, component, or config option
- Making optional parameters available
- Performance improvements without breaking anything
// Version 1.0.5
export function getUser()
// Version 1.1.0
export function getUser()
export function getUserAvatar() // new, optional
➡️ New version: 1.1.0
🔸 When to Bump PATCH (e.g. 1.0.5 → 1.0.6)
Increase the PATCH version when you fix bugs, make optimizations, or update things that don’t affect the public API.
✅ Examples:
- Fixing a typo or bug
- Improving internal performance
- Updating documentation only
// Before
function getUser() {
return fetch('/api/user') // broke in IE11
}
// After
function getUser() {
return fetchPolyfill('/api/user') // fix
}
➡️ New version: 1.0.6
🤔 Real-World Example: 1.0.5 → ?
Let’s say your current version is 1.0.5, and you add a new function that’s fully backward-compatible.
export function getUserData()
export function getUserAvatar() // new addition
Should the new version be:
1.0.6? ❌ No — this is not a bug fix.1.1.0? ✅ Yes — this is a new feature, no breaking changes.
🧠 Summary: Versioning Decision Table
| What Changed? | New Version | Why |
|---|---|---|
| ❌ Removed/renamed APIs | 2.0.0 | Breaking change |
| ✅ Added feature (non-breaking) | 1.1.0 | Compatible improvement |
| 🐛 Bug fix only | 1.0.6 | No new features or breaks |
| 📝 Docs / refactor only | 1.0.6 or same | No public change (optional) |
✍️ Final Thoughts
Semantic Versioning is not just for library maintainers — it’s a communication tool. It tells your users, teammates, and even your future self: what changed, and how safe is it to upgrade?
Next time you publish a release, ask yourself:
Did I break anything?
Did I add something?
Or did I just fix something?
Then you’ll always pick the right version number.
Happy versioning! 🎉
Bartłomiej Nowak
Programmer
Programmer focused on performance, simplicity, and good architecture. I enjoy working with modern JavaScript, TypeScript, and backend logic — building tools that scale and make sense.