Semantic versioning explained: what v1.4.1 means and when a change is really live
Semantic versioning explained for PMs: what MAJOR.MINOR.PATCH means, tags and GitHub releases, and why merged, released and live are different moments.
By Sergey BruhPublished 9 min read
Semantic versioning explained in one line: a version number has three parts, MAJOR.MINOR.PATCH, and each part tells you what kind of change happened. PATCH goes up for bug fixes, MINOR for new features that break nothing, MAJOR for changes that break something people rely on, and every number to the right of the one that went up resets to zero. So v1.4.1 reads as "the 1.4.0 feature release plus one patch of fixes". What a version number doesn't tell you is whether a customer can see a change. For a product manager that is the more useful half of the topic: merged, deployed, released and visible to every user are four different moments, and a version sits in the middle of them.
A quick case: "Which version is the fix in?"
Support at CatChow, an online pet-food shop, wants to tell customers "fixed in version so-and-so" about a checkout bug. The fix, pull request #134, was merged on a Wednesday at 9:40, and CatChow deploys every merge automatically, so it was on the live site by 9:44.
The honest answer that Wednesday was "no version". The team had a few old tags set by hand for big launches, the latest v1.3.0, and nothing since. On Thursday of the following week the team started a habit: every Thursday, the current main, already live, gets a version tag and release notes. The first one, v1.4.0, listed five merged pull requests, #134 among them.
The same release also listed the groundwork for a loyalty programme. That code was deployed too, but hidden behind a feature flag, so no customer could see it. The next morning support forwarded messages from customers who had found a menu link to the hidden programme, leading to an empty page. The two-line fix went out as v1.4.1, a PATCH release, because nothing else had been merged since v1.4.0.
So, which version has the checkout fix? "Fixed in 1.4.0 and in every version since." It had been live for more than a week before it got a version number. And the loyalty programme was "released" in v1.4.0 without a single customer seeing it.
The three numbers
Starting from 1.3.0:
- a fix gives
1.3.1; - a new feature gives
1.4.0(PATCH resets); - a breaking change gives
2.0.0(MINOR and PATCH reset).
A few details trip people up:
- Numbers, not letters. Each part is compared as a whole number, left to right.
1.4.10is newer than1.4.9, and1.10.0is newer than1.9.0. GitHub's tag list doesn't always sort them this way (as of 2026), so trust the numbers, not the order on the page. - Pre-releases. A suffix such as
2.0.0-beta.1marks a test version. It comes before2.0.0, and after every1.x. - Version zero.
0.y.zmeans initial development: anything may change at any time, and the rules above only really start at1.0.0. - The
v.v1.4.1is a common habit for naming tags. The version itself is1.4.1.
Who the promise is for
The official rules were written for software that other software depends on, such as libraries and APIs. There, "breaking" has a precise meaning: code that worked with version 1 stops working with version 2 unless someone changes it. A developer who sees a MAJOR bump knows to read the notes before upgrading.
A website or an app for consumers has no such contract, so the team has to decide what "breaking" means for it. CatChow's rule is one example: MAJOR if old links, saved carts or partner integrations stop working; MINOR for new features; PATCH for fixes only. Write your team's version of that rule down once, and version arguments become short.
Not every product uses semantic versioning. Some teams number by date, such as 2026.11, and many mobile apps show a "marketing version" that follows its own logic. Both are fine, as long as the team uses one scheme consistently.
Tags, releases and release notes on GitHub
A tag is a fixed name for one commit. A branch moves forward with every new commit; a tag stays where it was put. That is why versions are tags. Technically a tag can be deleted and recreated, but a published one should never move: people and tools rely on v1.4.0 meaning the same code forever.
A release on GitHub is a page built on a tag, with notes and optional files. As of 2026, the form under Releases → Draft a new release lets you pick or create a tag, choose the previous tag and press Generate release notes, which lists every pull request merged since that tag with its title and author. Two checkboxes matter: Set as a pre-release for test versions and Set as the latest release, which gives the page a Latest badge. Latest means the newest full release, not "just deployed".
The generated list is raw material, written for engineers. A changelog is the human version: what changed, in words customers and support understand. A useful pattern is a short "For customers and support" section on top, in plain words, with the generated list below it. That section is also where you make sure hidden work stays hidden: nothing behind a flag gets announced.
Good pull request titles pay off twice here. "Fix checkout button after cart edits" makes a readable line in the notes; "Daniel's branch" doesn't.
Merged, deployed, released, visible
How far apart these are depends on the team. At CatChow, merged and deployed are minutes apart, a release follows on Thursday, and a flag can keep a feature invisible for weeks after all three. In a mobile team using git flow, the order is different: merged into develop, released weeks later, then store review, a gradual rollout to a growing share of users, and finally each user updating the app. The comparison of GitHub flow vs git flow explains why the models differ.
When someone asks "is it live?", first ask yourself which of the four they mean. Marketing usually means "visible to every customer"; support means "fixed for the customer on the phone right now".
How to answer "which version has fix #N?"
- Open the pull request. If it isn't merged, no version has it.
- Find its commit on
main. With squash merging, each pull request becomes one commit onmainwhose title ends in(#N), so the pull request page links straight to it. - Check the tags. As of 2026, a commit's page lists the tags that contain it. The oldest of them is the first version with the fix.
- Or compare two versions. The compare view, such as
v1.4.0...v1.4.1, shows exactly what was added between two tags. - Or read the release notes in order. Find the first version whose notes mention the fix. Every later version contains it too, unless a later note says it was reverted.
The answer support can forward: "Fixed in 1.4.0 and every version since."
Common mistakes
Reading release notes as the whole content of a version. Notes list only what is new since the previous version. v1.4.1 doesn't mention the checkout fix, and still contains it.
Announcing everything in a release. A feature can be in a release and invisible behind a flag. Check flags before you write the announcement.
Treating "Latest" or "published" as "deployed". In teams that deploy on merge, the code was live before the release existed. In others, publishing a release triggers the deploy. Ask which one is yours.
Calling a feature release a patch. If anything new slipped in since the last tag, the honest bump is MINOR, even when the reason for releasing was a fix.
Moving a tag. Re-pointing v1.4.0 at different code breaks every conversation and tool that referred to it. Make a new version instead.
What to do this week
- Open your product's
ReleasesandTagspages. What was the last version, and when? - Ask how your team decides between MAJOR, MINOR and PATCH, and write the rule down if nobody has.
- Take one fix you care about and find the first version that contains it.
- Offer to write the plain-language part of the next release notes.
Key takeaways
- MAJOR.MINOR.PATCH: breaking changes, new features, fixes. Numbers to the right reset.
- Compare versions as numbers:
1.4.10is newer than1.4.9. - A tag names one commit forever; a GitHub release is a page with notes on a tag.
- Merged, deployed, released and visible can be four different moments.
- A version contains everything before it on the same line, not only what its notes list.
FAQ
What does v1.4.1 mean?
Major version 1, minor version 4, and the first patch on top of 1.4.0. Under semantic versioning, 1.4.1 should contain nothing new compared with 1.4.0, only fixes.
What does a version starting with 0 mean?
That the product or library is in initial development and anything may change without a MAJOR bump. Many teams move to 1.0.0 when they are ready to promise stability.
Does publishing a GitHub release deploy the code?
Not by itself. A release is a page with notes on a tag. Some teams set up automation so that publishing a release starts a deploy; others, like teams that deploy every merge, publish the release after the code is already live.
How is a changelog different from release notes?
Often they are the same thing in different places. Release notes live on each release page; a changelog collects every version's changes in one place, sometimes as a CHANGELOG.md file. Either way, write it for people, not for Git.
Learn it hands-on
The lesson Releases and versions: tags, SemVer, changelogs walks through CatChow's first weekly release and the hotfix the next morning, with practice on version numbers and release notes checked by AI. GitHub flow covers merged vs deployed and feature flags, and Merging explains squash merges and why each pull request becomes one commit on main. They are part of the free course Git and GitHub for Product People.