# Semantic versioning (SemVer) explained: what v1.4.1 means and when a change is really live

> Semantic versioning (SemVer) explained for PMs: what major, minor and patch mean, tags and GitHub releases, and why merged and live are different moments.

- Source: https://productovi.com/blog/semantic-versioning-explained
- By: Sergey Bruh
- Published: 2026-10-02
- Topics: Releases, tags and versions, GitHub flow, Merging: merge commit, squash, rebase

Semantic versioning (SemVer), 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.

## Major, minor, patch: the three numbers

| Part  | Goes up when                                   | Product examples                                                             |
| ----- | ---------------------------------------------- | ---------------------------------------------------------------------------- |
| PATCH | Only fixes, nothing new                        | A wrong footer link, a typo in the cart, a crash on login                    |
| MINOR | New features that keep everything else working | A gift note at checkout, a new delivery option, a loyalty programme          |
| MAJOR | Something people rely on stops working         | Removed API fields, changed page addresses, a new import format for partners |

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.10` is newer than `1.4.9`, and `1.10.0` is newer than `1.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.1` marks a test version. It comes before `2.0.0`, and after every `1.x`.
- **Version zero.** `0.y.z` means initial development: anything may change at any time, and the rules above only really start at `1.0.0`.
- **The `v`.** `v1.4.1` is a common habit for naming tags. The version itself is `1.4.1`.

## Does semantic versioning fit a website or an app?

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 use date-based version numbering, 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

| Moment   | What it means                                | Where to check                                            |
| -------- | -------------------------------------------- | --------------------------------------------------------- |
| Merged   | The change is accepted into a branch         | The pull request says "Merged" and names the branch       |
| Deployed | That code is running on the live servers     | The deploy job, or `Deployments` on the repository page   |
| Released | A version containing it has a name and notes | The `Releases` page, the tags that contain the commit     |
| Visible  | Customers can actually see and use it        | Feature flag settings, rollout status, the product itself |

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](/blog/github-flow-vs-git-flow) explains why the models differ.

![The checkout fix was merged, deployed and visible within minutes but got a version a week later; the loyalty groundwork was deployed and released yet stayed hidden behind a feature flag](/blog/semantic-versioning-explained/diagram.png)

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?"

1. **Open the pull request.** If it isn't merged, no version has it.
2. **Find its commit on `main`.** With squash merging, each pull request becomes one commit on `main` whose title ends in `(#N)`, so the pull request page links straight to it.
3. **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.
4. **Or compare two versions.** The compare view, such as `v1.4.0...v1.4.1`, shows exactly what was added between two tags.
5. **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

1. Open your product's `Releases` and `Tags` pages. What was the last version, and when?
2. Ask how your team decides between MAJOR, MINOR and PATCH, and write the rule down if nobody has.
3. Take one fix you care about and find the first version that contains it.
4. 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.10` is newer than `1.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](/courses/git-for-product/releases-and-versions/theory) 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](/courses/git-for-product/github-flow/theory) covers merged vs deployed and feature flags, and [Merging](/courses/git-for-product/merging/theory) 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](/courses/git-for-product).

## Related lessons

- [GitHub releases and versions: tags, SemVer, changelogs](https://productovi.com/courses/git-for-product/releases-and-versions.md)
- [GitHub flow: small branches, fast merges](https://productovi.com/courses/git-for-product/github-flow.md)
- [Merging on GitHub: merge commit, squash and merge, rebase](https://productovi.com/courses/git-for-product/merging.md)
