Why PATCH is for Bug Fixes only? #543

Open
opened 2026-02-17 12:12:14 -06:00 by GiteaMirror · 14 comments
Owner

Originally created by @felipecrs on GitHub (May 2, 2022).

Why it isn't the following?

1. MAJOR version when you make incompatible API changes,
2. MINOR version when you add functionality in a backwards compatible manner, and
- 3. PATCH version when you make backwards compatible bug fixes.
+ 3. PATCH version when you make backwards compatible changes that does not add functionality.

I just want to know why PATCH bumps are reserved to only Bug Fixes.

What about backwards compatible Performance Improvements, Refactoring, Dependency Updates, Documentation (that gets shipped with the product), for example? None of them are Bug Fixes, and yet deserves to be released (no?).

Originally created by @felipecrs on GitHub (May 2, 2022). Why it isn't the following? ```diff 1. MAJOR version when you make incompatible API changes, 2. MINOR version when you add functionality in a backwards compatible manner, and - 3. PATCH version when you make backwards compatible bug fixes. + 3. PATCH version when you make backwards compatible changes that does not add functionality. ``` I just want to know why `PATCH` bumps are reserved to only Bug Fixes. What about backwards compatible Performance Improvements, Refactoring, Dependency Updates, Documentation (that gets shipped with the product), for example? None of them are Bug Fixes, and yet deserves to be released (no?).
Author
Owner

@jcornaz commented on GitHub (May 3, 2022):

Yeah, fully agree. Personally, I bump the patch component notably for performance and documentation improvements.

However, for exact wording I would suggest something like:

PATCH version when you make backwards compatible changes that do not change the API

as semver is all about the declared API:

  • major = incompatible API change
  • minor = compatible API change
  • patch = no API change
@jcornaz commented on GitHub (May 3, 2022): Yeah, fully agree. Personally, I bump the patch component notably for performance and documentation improvements. However, for exact wording I would suggest something like: ``` PATCH version when you make backwards compatible changes that do not change the API ``` as semver is all about the [declared API](https://semver.org/#spec-item-1): * major = incompatible API change * minor = compatible API change * patch = no API change
Author
Owner

@JoshCheek commented on GitHub (May 20, 2022):

I've always bumped the minor version in these situations, I guess I've always thought of them as being closer to features than bugfixes. But if I use @jcornaz's metrics, then yeah, I agree that they'd be patchlevel.

@JoshCheek commented on GitHub (May 20, 2022): I've always bumped the minor version in these situations, I guess I've always thought of them as being closer to features than bugfixes. But if I use @jcornaz's metrics, then yeah, I agree that they'd be patchlevel.
Author
Owner

@epage commented on GitHub (May 31, 2022):

minor = compatible API change
patch = no API change

imo distinguishing between no API change and compatible API change has little impact on the callers lives. The distinction I tend towards is either

  • Do the changes, in aggregate, increase risk for the caller to worry about when upgrading?
  • Do the semantic changes, in aggregate, need their visibility raised because they might break someone despite it being a bug / undefined behavior?

Or put another way "what is the chance I would need the flexibility to release a hotfix for this release?" (if we were doing hotfixes)

@epage commented on GitHub (May 31, 2022): > minor = compatible API change > patch = no API change imo distinguishing between no API change and compatible API change has little impact on the callers lives. The distinction I tend towards is either - Do the changes, in aggregate, increase risk for the caller to worry about when upgrading? - Do the semantic changes, in aggregate, need their visibility raised because they might break someone despite it being a bug / undefined behavior? Or put another way "what is the chance I would need the flexibility to release a hotfix for this release?" (if we were doing hotfixes)
Author
Owner

@jcornaz commented on GitHub (May 31, 2022):

imo distinguishing between no API change and compatible API change has little impact on the callers lives.

Yes. Sure. That's by definition. The only thing that has a big impact on callers lives is: breaking changes. And breaking changes require major bump. As long as a change is not breaking the API, further details have little impact on the callers live. Not to say it has none. I still find it valuable to know from a version number if the API has changed or not.

But there is still a difference that matters for the user. If we think about how easy/risky it is to downgrade:

  • major: cannot upgrade to a major version nor downgrade from a major verision without risk
  • minor: can upgrade safely, but cannot downgrade from a minor version (as the new API introduced by the version may be already in use)
  • patch: can upgrade and downgrade safely, as there is no API change.
@jcornaz commented on GitHub (May 31, 2022): > imo distinguishing between no API change and compatible API change has little impact on the callers lives. Yes. Sure. That's by definition. The only thing that has a big impact on callers lives is: breaking changes. And breaking changes require major bump. As long as a change is not breaking the API, further details have little impact on the callers live. Not to say it has none. I still find it valuable to know from a version number if the API has changed or not. But there is still a difference that matters for the user. If we think about how easy/risky it is to *downgrade*: * major: cannot upgrade to a major version nor downgrade from a major verision without risk * minor: can upgrade safely, but cannot downgrade from a minor version (as the new API introduced by the version may be already in use) * patch: can upgrade and downgrade safely, as there is no API change.
Author
Owner

@epage commented on GitHub (May 31, 2022):

But there is still a difference that matters for the user. If we think about how easy/risky it is to downgrade:

patch: can upgrade and downgrade safely, as there is no API change.

Except there are bug fixes that make it unsafe to downgrade.

@epage commented on GitHub (May 31, 2022): > But there is still a difference that matters for the user. If we think about how easy/risky it is to downgrade: > > patch: can upgrade and downgrade safely, as there is no API change. Except there are bug fixes that make it unsafe to downgrade.
Author
Owner

@jwdonahue commented on GitHub (Nov 18, 2022):

Adding functionality does not necessarily increase or modify the interface, so the proposed new language has a similar flaw to the original. A library might have a SoundOn interface for instance that was never implemented in the package. The 'I' in API stands for Interface, not implementation, but the spec's intro says the publisher decides what API means in the context of their product.

Addressing the OP's original question:

Why PATCH is for Bug Fixes only?

In practice it is not just for bug fixes. What it applies to is context dependent, where context includes things like:

  • Tool chains.
    • Programing/content language.
    • Compilers, linkers, interpreters.
    • Packaging tools.
  • Runtime environment(s).
  • Ecosystem expectations.
  • What is being versioned.
  • Too many other things to list here.

What about backwards compatible Performance Improvements, Refactoring, Dependencies Updates, Documentation (that gets shipped with the product), for example?

Again context matters:

  • In some cases any change in performance could be a breaking change.
  • Refactoring can cause changes in performance or break things that are dependent on content.
  • For dependencies, see all the discussions around transitive dependencies.
  • Documentation changes can be tricky as well, particularly if the language indicates that something that seemed to be supported is, or should, no longer be supported.

The spec's authors have never attempted to cover all use cases. It's not the most well written specification, but it has sufficed to convey the gist of the original author's intent at the time.

@jwdonahue commented on GitHub (Nov 18, 2022): Adding functionality does not necessarily increase or modify the interface, so the proposed new language has a similar flaw to the original. A library might have a SoundOn interface for instance that was never implemented in the package. The 'I' in API stands for Interface, not implementation, but the spec's intro says the publisher decides what API means in the context of their product. Addressing the OP's original question: > Why PATCH is for Bug Fixes only? In practice it is not just for bug fixes. What it applies to is context dependent, where context includes things like: - Tool chains. - Programing/content language. - Compilers, linkers, interpreters. - Packaging tools. - Runtime environment(s). - Ecosystem expectations. - What is being versioned. - Too many other things to list here. > What about backwards compatible Performance Improvements, Refactoring, Dependencies Updates, Documentation (that gets shipped with the product), for example? Again context matters: - In some cases any change in performance could be a breaking change. - Refactoring can cause changes in performance or break things that are dependent on content. - For dependencies, see all the discussions around [transitive dependencies](https://github.com/semver/semver/issues?q=transitive+dependency). - Documentation changes can be tricky as well, particularly if the language indicates that something that seemed to be supported is, or should, no longer be supported. The spec's authors have never attempted to cover all use cases. It's not the most well written specification, but it has sufficed to convey the gist of the original author's intent at the time.
Author
Owner

@felipecrs commented on GitHub (Nov 18, 2022):

Thanks for the answer!

In practice it is not just for bug fixes.

But my concern is about the theory, which is what this specification is.

Again context matters:

That's why I started the sentence being explicitly clear that I'm talking about backwards compatible, i.e. non breaking changes.

The spec's authors have never attempted to cover all use cases. It's not the most well written specification, but it has sufficed to convey the gist of the original author's intent at the time.

I understand. But it may be something to have in mind for a newer version of the specification.

@felipecrs commented on GitHub (Nov 18, 2022): Thanks for the answer! > In practice it is not just for bug fixes. But my concern is about the theory, which is what this specification is. > Again context matters: That's why I started the sentence being explicitly clear that I'm talking about backwards compatible, i.e. non breaking changes. > The spec's authors have never attempted to cover all use cases. It's not the most well written specification, but it has sufficed to convey the gist of the original author's intent at the time. I understand. But it may be something to have in mind for a newer version of the specification.
Author
Owner

@jcornaz commented on GitHub (Nov 18, 2022):

The spec's authors have never attempted to cover all use cases. It's not the most well written specification, but it has sufficed to convey the gist of the original author's intent at the time.

I think a good specification minimizes the risk of diverging interpretations. SemVer should aim to maximize its clarity and applicability.

Tool chains.
Programing/content language.
Compilers, linkers, interpreters.
Packaging tools.
Runtime environment(s).
Ecosystem expectations.
What is being versioned.
Too many other things to list here.

In some cases any change in performance could be a breaking change.

There is already a clear rule about breaking change. If it is a breaking change, bump the major version.

Refactoring can cause changes in performance or break things that are dependent on content.

If it changes something in the API (incl. changing documented behavior), then it is not refactoring.
"refactoring" means changing the implementation without changing the API or the behavior.

If you promised behavior or performance in your documentation, then a change that would violate those promises should be considered as breaking (major bump). If you didn't document the behavior or perf or you still deliver the promised behavior and perf, then bump the patch.

For dependencies, see all the discussions around transitive dependencies.
Documentation changes can be tricky as well, particularly if the language indicates that something that seemed to be supported is, or should, no longer be supported.

The same concept applies...

Of course, it is sometimes (often?) tricky to determine what is a breaking change and what is not. Personally, I like very much the documentation on what constitutes a breaking change for the rust ecosystem: https://github.com/rust-lang/rfcs/blob/master/text/1105-api-evolution.md

But the present issue is not discussing the wording of what constitutes a breaking change. It is discussing the wording of what constitutes a patch change. I think it is already clear that to be a patch it should be neither breaking nor a feature.

@jcornaz commented on GitHub (Nov 18, 2022): > The spec's authors have never attempted to cover all use cases. It's not the most well written specification, but it has sufficed to convey the gist of the original author's intent at the time. I think a good specification minimizes the risk of diverging interpretations. SemVer should aim to maximize its clarity and applicability. > Tool chains. > Programing/content language. > Compilers, linkers, interpreters. > Packaging tools. > Runtime environment(s). > Ecosystem expectations. > What is being versioned. > Too many other things to list here. > In some cases any change in performance could be a breaking change. There is already a clear rule about breaking change. If it is a breaking change, bump the major version. > Refactoring can cause changes in performance or break things that are dependent on content. If it changes something in the API (incl. changing documented behavior), then it is not refactoring. "refactoring" means changing the implementation without changing the API or the behavior. If you promised behavior or performance in your documentation, then a change that would violate those promises should be considered as breaking (major bump). If you didn't document the behavior or perf or you still deliver the promised behavior and perf, then bump the patch. > For dependencies, see all the discussions around [transitive dependencies](https://github.com/semver/semver/issues?q=transitive+dependency). > Documentation changes can be tricky as well, particularly if the language indicates that something that seemed to be supported is, or should, no longer be supported. The same concept applies... Of course, it is sometimes (often?) tricky to determine what is a breaking change and what is not. Personally, I like very much the documentation on what constitutes a breaking change for the rust ecosystem: https://github.com/rust-lang/rfcs/blob/master/text/1105-api-evolution.md But the present issue is not discussing the wording of what constitutes a breaking change. It is discussing the wording of what constitutes a *patch* change. I think it is already clear that to be a patch it should be neither breaking nor a feature.
Author
Owner

@jwdonahue commented on GitHub (Nov 18, 2022):

I think a good specification minimizes the risk of diverging interpretations. SemVer should aim to maximize its clarity and applicability

Spend some time reading all of the closed issues on this site and you'll likely come to the conclusion that I did, namely that that is not the intent of the maintainers. The maintainers are package tool owners serving diverse ecosystems. There are many, much tighter specs out there, mostly for very narrowly defined use cases.

If it changes something in the API (incl. changing documented behavior), then it is not refactoring.
"refactoring" means changing the implementation without changing the API or the behavior.

Just pointing out to the OP that refactorings are not always patch level changes.

I think it is already clear that to be a patch it should be neither breaking nor a feature.

Exactly!

The issue here is many people suggest modifying the spec to make it more clear, or to cover a use case they perceive to be useful, most of which would require a major version bump on the spec itself. Just about everybody can think of ways to clarify the language with respect to how they perceive that it should be applied, but nobody wants to put in the work that would cover all the ways it is currently applied. Attempting to do so would would require more words and for every one of those you add to it, the range of possible interpretations will either increase such that it is less clear or be restricted, such that it breaks a sizable fraction of the currently "SemVer compliant" implementations.

The maintainers have been reluctant to discuss SemVer 3. They own packaging tools that serve large silos, each of which has its own peculiar needs and practices. In that sense, the SemVer spec has been a huge success so far.

@jwdonahue commented on GitHub (Nov 18, 2022): > I think a good specification minimizes the risk of diverging interpretations. SemVer should aim to maximize its clarity and applicability Spend some time reading all of the closed issues on this site and you'll likely come to the conclusion that I did, namely that that is not the intent of the maintainers. The maintainers are package tool owners serving diverse ecosystems. There are many, much tighter specs out there, mostly for very narrowly defined use cases. > If it changes something in the API (incl. changing documented behavior), then it is not refactoring. "refactoring" means changing the implementation without changing the API or the behavior. Just pointing out to the OP that refactorings are not always patch level changes. > I think it is already clear that to be a patch it should be neither breaking nor a feature. Exactly! The issue here is many people suggest modifying the spec to make it more clear, or to cover a use case they perceive to be useful, most of which would require a major version bump on the spec itself. Just about everybody can think of ways to clarify the language with respect to how they perceive that it should be applied, but nobody wants to put in the work that would cover all the ways it is _currently_ applied. Attempting to do so would would require more words and for every one of those you add to it, the range of possible interpretations will either increase such that it is less clear or be restricted, such that it breaks a sizable fraction of the currently "SemVer compliant" implementations. The maintainers have been reluctant to discuss SemVer 3. They own packaging tools that serve large silos, each of which has its own peculiar needs and practices. In that sense, the SemVer spec has been a huge success so far.
Author
Owner

@jcornaz commented on GitHub (Nov 18, 2022):

So we are doomed and any effort to improve the spec is in vain. We are left with a versioning spec that is not even good enough to version itself and that every developer understands differently and argues about. I've even seen people refusing to release a new version of the software that's full of CVE, because "there is no functional change".

Sadly, it does look like that is the case indeed. Not that I am happy about it. Personally, I have stopped saying on my projects that they follow semantic versioning, as different people will understand it differently anyway.

@jcornaz commented on GitHub (Nov 18, 2022): So we are doomed and any effort to improve the spec is in vain. We are left with a versioning spec that is not even good enough to version itself and that every developer understands differently and argues about. I've even seen people refusing to release a new version of the software that's full of CVE, because "there is no functional change". Sadly, it does look like that is the case indeed. Not that I am happy about it. Personally, I have stopped saying on my projects that they follow semantic versioning, as different people will understand it differently anyway.
Author
Owner

@jwdonahue commented on GitHub (May 3, 2023):

Personally, I have stopped saying on my projects that they follow semantic versioning, as different people will understand it differently anyway.

SemVer is just one of many semantic versioning schemes.

@jwdonahue commented on GitHub (May 3, 2023): > Personally, I have stopped saying on my projects that they follow semantic versioning, as different people will understand it differently anyway. SemVer is just one of many semantic versioning schemes.
Author
Owner

@ljharb commented on GitHub (May 3, 2023):

It's the only one that has any kind of adoption though, so it's pretty reasonable to conflate the two terms.

@ljharb commented on GitHub (May 3, 2023): It's the only one that has any kind of adoption though, so it's pretty reasonable to conflate the two terms.
Author
Owner

@Nikasyo25 commented on GitHub (May 4, 2023):

What is it for
Why I'm receiving this email?

On Thu, 4 May 2023, 12:22 am Jordan Harband, @.***>
wrote:

It's the only one that has any kind of adoption though, so it's pretty
reasonable to conflate the two terms.


Reply to this email directly, view it on GitHub
https://github.com/semver/semver/issues/831#issuecomment-1533874367, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/A3FXP3LZDBEZUOL4CL5ABODXELSBVANCNFSM5U5IJLYQ
.
You are receiving this because you are subscribed to this thread.Message
ID: @.***>

@Nikasyo25 commented on GitHub (May 4, 2023): What is it for Why I'm receiving this email? On Thu, 4 May 2023, 12:22 am Jordan Harband, ***@***.***> wrote: > It's the only one that has any kind of adoption though, so it's pretty > reasonable to conflate the two terms. > > — > Reply to this email directly, view it on GitHub > <https://github.com/semver/semver/issues/831#issuecomment-1533874367>, or > unsubscribe > <https://github.com/notifications/unsubscribe-auth/A3FXP3LZDBEZUOL4CL5ABODXELSBVANCNFSM5U5IJLYQ> > . > You are receiving this because you are subscribed to this thread.Message > ID: ***@***.***> >
Author
Owner

@Velocifyer commented on GitHub (Jun 13, 2025):

I also was wondering this. Currently for my code i just pertend that the third integer is for any changes that dont change the public api

@Velocifyer commented on GitHub (Jun 13, 2025): I also was wondering this. Currently for my code i just pertend that the third integer is for any changes that dont change the public api
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/semver#543