mirror of
https://github.com/semver/semver.git
synced 2026-07-11 03:53:53 -05:00
[GH-ISSUE #641] [Suggestion] Considering add another VERSION NUMBER before MAJOR version #4689
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @yarcowang on GitHub (Nov 22, 2020).
Original GitHub issue: https://github.com/semver/semver/issues/641
Currently, the version number is as following in the summary:
But in modern times, there also exists another big change like Developing Language changed, or Use another framework. I think those changes are more important than the MAJOR version change can express.
So, I suggest adding a FRAMEWORK/LANGUAGE level version number in the specification. And it also won't break the current specification if you don't need such big change. MAJOR.MINOR.PATCH should still work.
The real examples as I said are for example:
It is hard to distinguish those changes from the names and also it is not very clear about the relationships between NAME<VERSION_NUMBER> and the version numbers in the SemVer specification.
If VERSION_NUMBER == MAJOR change, then MAJOR version can not be changed in for example Angular2 project.
Conclusion: this suggestion is just an extension of the current specification, it doesn't harm anything if you don't need such change in your project. It only pays attention to those big projects need a great change, and make sure the SemVer grammar can still express those changes.
Thank you.
Addition thinking: maybe it can parallelly expressing framework change and api doesn't change, ex.: 0.0.0.1 to 1.0.0.1 can mean "we change the framework/programming language, but the API still the same"? (And of course, I think it might rarely happen in real)
++
This idea is coming from one of my requirements when I'm thinking I want to do a fast prototype project which might use PHP, if the project name is ABC.
And then I want to improve it or some parts might be changed into the different programming language as nowadays we are following microservice structure if for example, use rust/golang.
How they are grouped in the repository is not what I care about, I want a way to express those changes:
from ABC in PHP to ABC in PHP & rust/golang, but there's no such mapping in current SemVer specification for it does a big change, but it is not "incompatible API changes" or "add functionality" or "bug fix"
@ljharb commented on GitHub (Nov 22, 2020):
The best way to communicate that kind of change is with a project name change.
@yarcowang commented on GitHub (Nov 22, 2020):
@ljharb Yes, but what is the specification of those "name change", add a suffix number? And then there will be confusion of these numbers and the SemVer numbers.
@ljharb commented on GitHub (Nov 22, 2020):
No, i mean, at that point it’s a different project and should be treated as something entirely distinct.
@yarcowang commented on GitHub (Nov 22, 2020):
@ljharb You can set up another repository for that project, of course, but there's still the relationship between drupal7 and drupal8 as I mentioned in the examples.
Git or github doesn't need to change, but the meaning can be expressed in the SemVer specification.
That is, can be set up as two projects:
Let the user choose how to organize the structure.
@Ipirius commented on GitHub (Nov 27, 2020):
TBH, Rewriting your code without changes to api or adding features sounds like just PATCH to me, even if you change the framework or language.
@ljharb commented on GitHub (Nov 27, 2020):
@Ipirius as long as you change zero of the underlying platform requirements and support, that’s true.
@yarcowang commented on GitHub (Nov 30, 2020):
@Ipirius Well, that depends on the people's feelings ~ I'm not quite sure. But to me, it should be marked as a great change (when framework/language changed).
@Nixinova commented on GitHub (Jan 12, 2021):
Adding another digit is surely out of scope on SemVer at this point.
If you really want 4 digits to avoid bumping major for every tiny breaking change I have created the dynamic versioning spec which splits the "<major>" part into "<Disruptive>.<Incomparable>", i.e. "major breaking change, minor breaking change".
@rite2hhh commented on GitHub (Feb 15, 2021):
It's not about versioning the code, it's about versioning the API.
You have to think about projects that use SemVer for changes from the end-user's perspective. Underlying frameworks can change all you want, but if the API is intact, it's just a PATCH
@Nixinova commented on GitHub (Feb 15, 2021):
Is that not the whole point of SemVer? Being from a users perspective.
@rite2hhh commented on GitHub (Feb 15, 2021):
Yes it is. But developers construe "MAJOR" changes from their perspective as "MAJOR" changes for the user too i.e. public API, which isn't what SemVer is about is it?
If project1 written in frameworkX functions exactly the same if written in frameworkY, then the version change is simply from X.Y.0 -> X,Y,1 (given X > 0)
@juventus18 commented on GitHub (Apr 1, 2021):
It seems to me that many projects attempt to use the
<major>position to sync their project to a major version of a larger project. For example, Nuxtjs uses major version 2.x.x to denote that it is compatible with Vue 2.x.x and Nuxt 3.x.x is compatible with Vue 3.x.x. While this makes it much easier for humans to understand, it created a bit of a problem recently when Nuxt wanted to make a breaking change. If they incremented the<major>, then they lose the version sync with the required Vue version. So they instead applied a breaking change on a<minor>increment. Now, I understand that you may say "then that's not Semver" but isn't the point of the spec to increase adoption of standards? This seems to be a common enough scenario that could be accounted for in SemVer, thus increasing adoption. Perhaps something like<bounded>.<major>.<minor>.<patch>. If this were implemented, going back to my example, Nuxt would be able to keep version sync with Vue by using the<bounded>and incrementing their<major>as normal on the breaking change. The<bounded>would be optional.@ljharb commented on GitHub (Apr 1, 2021):
@juventus18 no, the point of the spec is to document the standard. Things that choose to violate the standard have made that choice; the spec doesn't need to accommodate them.
@juventus18 commented on GitHub (Apr 1, 2021):
@ljharb Why make a standard in the first place if you don't want people to adopt it? I think this leads to 'competing standards' which limits interoperability (i.e. right now, NPM pretty much operates on SemVer spec, causing the above issue). The current spec is omitting a major use case that is quite common. If Nuxt followed current SemVer, it actually makes it harder and more confusing for the end-user (developer) rather than easier, which seems to be at odds with declaring a standard (common language) to begin with.
@ljharb commented on GitHub (Apr 1, 2021):
semver is quite widely adopted. in the npm ecosystem, projects that don't follow semver are castigated for it.
I don't think this use case is quite common in practice - i think that conflating the version with something else quickly demonstrates to maintainers this exact problem, and then they stop doing it. That Nuxt chose to drop semver rather than dropping their syncing pattern is surprising and wildly unidiomatic for the npm ecosystem.
@juventus18 commented on GitHub (Apr 1, 2021):
@ljharb If they stop syncing their major version number and follow SemVer as it is currently written, then I will have to go check their docs every time a new major version comes out in order to tell whether it is compatible with my underlying version of the Vue framework. Isn't that what SemVer is meant to address anyway? A way to quickly and semantically identify whether a given version will break without having to explicitly look at the docs. Quoting from the SemVer intro:
Under the current SemVer, there is no way to really convey the meaning that the underlying Nuxt code has been modified to a newer version of the base framework (Vue) as a breaking change, or if the breaking change is due to Nuxt's API.
In my specific example, since Nuxt is compatible with Vue2 and Vue3 (depending on Nuxt version) Following current SemVer procedures for version incrementing would actually 'trap' them into releasing version numbers that are inherently non-semantic.
@ljharb commented on GitHub (Apr 1, 2021):
You won't have to check the docs nor did you ever; that's what
peerDependenciesare for.npm lsreports on these, and npm 7+ reports on them during install as well.In other words, Nuxt would need to declare a peer dep on the appropriate versions of vue, and then you don't need syncing, or to rely on prose, to ensure compatibility.
@juventus18 commented on GitHub (Apr 1, 2021):
@ljharb I should have said "... without explicitly looking outside of the SemVer" (i.e. the meaning is not conveyed, as SemVers stated goal proposes).
The current state "breaks" the "Semantic" part of SemVer IMO. We could end up in a scenario where versions 1.x.x, 2.x.x, 3.x.x, 5.x.x depend on Vue 2 and version 4.x.x depends on Vue 3, where version 4.x.x actually contains the "most updated" code (when semantically, one would think version 5.x.x would be the "most updated"). With my proposed changes, the version numbers become 2.1.x.x, 2.2.x.x, 2.3.x.x, 2.4.x.x for Vue 2 and 3.1.x.x for Vue 3. Thus, maintaining semantic meaning.
@ljharb commented on GitHub (Apr 1, 2021):
A package's semver version only conveys breakage - that's the only semantic it offers. It does not convey dependencies, that always is separate. Attempting to abuse it to convey compatibility with other things is not what it's for.
@juventus18 commented on GitHub (Apr 1, 2021):
@ljharb Then how should I increment my version number if I have not made incompatible public API changes, but I have updated an underlying dependency (which would cause breakage)?
@Nixinova commented on GitHub (Apr 1, 2021):
If the dependency will break your software, major. If it wont, patch.
@juventus18 commented on GitHub (Apr 1, 2021):
@Nixinova but the spec doesn't say "if it breaks" it says "...if any backwards incompatible changes are introduced to the public API" (emphasis added) - but they weren't in my example scenario.
My lib
v1.0.0
v?.?.?
@ljharb commented on GitHub (Apr 1, 2021):
The public API includes every transitive dependency it invokes. In the case you're describing, that's just a patch, obviously.
If it were a peer dep, however, that peer dep is part of your API as well, so updating its major version would always be breaking.
@juventus18 commented on GitHub (Apr 1, 2021):
@ljharb
I think that's what I needed to understand your position, thanks! I'll have to think about it more to see if it actually resolves my concerns, but this explanation at least "makes sense" to me at face value. TA for the expanded conversation, much appreciated. 👍
@yarcowang commented on GitHub (Apr 3, 2021):
I think a
code nameis better in this case, as in(though macosx is not the case I expressed)
Name "Code Name" SemVer
So, they should name "AngularJs" as:
AngularJs "Tiger" x.y.z
AngularJs "Leopard" x.yz
...
@emkyle2025-tech commented on GitHub (Aug 22, 2025):
Prism I have lasers old from day 1 prism plus computer parts and systems ought always be busted but not like this