Semantic versing(SemVer) is the most used software versioning system. In this article, we are discussing Semantic versioning in detail. All aspects will be discussed- from structure to all prefixes and postfixes.
Semantic Versioning(SemVer) is a method of assigning version numbers to each released version of software that indicates the scope of the changes made in that release.
Software release needs versioning to identify and differentiate between different released features(and bug fixes) and keep a change history.
We see SemVer all over the place, from popular open-source software releases to libraries and packages(npm, composer, etc.).
Basic SemVer Structure
SemVer has 3 main parts. Here are the parts form Left to Right-
- Major
- Minor
- Patch
The major, minor, and patch are positive numbers, and are incremental. Each part is separated from the other, using a dot(.).
Here is what each part means and what type of changes can be done for those parts-
Part of SemVer | Meaning(if changed) | Backward Compatible | Impacted Areas/Users | What changes can we do(as part of this change) |
---|---|---|---|---|
Major | Indicates breaking changes in: – API – Feature | No | All users using the code | – Breaking API change. – Deprecated feature removal. – Big refactoring of code. – New feature that changes existing code behavior. |
Minor | New features are implemented | Yes | User of the new features added in this version | – New features(without impacting existing behavior) – Deprecate old API/feature (without removing it) – Performance improvements |
Patch | Bug fix or security issue fix | Yes | Users which were using the buggy features of the old version | – Bug fix. – Security patches. – Minor internal optimization/change (without any change in functionality). |
SemVer Rules
Follow these rules when you use Semantic Versioning for the release of software-
- The software must have clear documentation and/or code comment and/or annotation and/or public declaration of the API/interface that is released. So that other users(developers or applications) are aware of the usage of the software and what changes are made in each released version.
- Parts(Major, Minor, Patch) of the SemVer are positive integer numbers.
- Parts(Major, Minor, Patch) of the SemVer are separated by dots(.).
- With each release, the parts(Major, Minor, Patch) of the Semver should increase. It can not go backward. One part can be initialized to a lower number, if the more significant part is increased.
- For initial development, the major version should be Zero(0), it will be in the form 0.B.C (where B and C are positive integers). If the major version is Zero(0) that means, the version is not stable and the API may or may not be public.
- Any version greater than or equal to 1.0.0 means a stable release, and must have a publically available API.
- The parts(Major, Minor, Patch) of SemVer are not limited to 0-9 (Zero to Nine) or 0-10 (Zero to Ten), these numbers can be any positive integer.
- For a prerelease version, we can use “alpha”, “beta”, etc. separated by a hyphen(-). For example 1.0.0-alpha
Examples
Check the following examples, where we are showing what it means for the changes in the different parts of SemVer, and what are the possible cases-
Update from Version | Update to Version | Description | Note |
---|---|---|---|
0.1.0-alpha | Initial feature implementations. Moving version from internal testing. This is not publically available. | Internal testing | |
0.1.0-alpha | 0.1.0-alpha.1 | Bug/security fix done on 0.1.0-alpha | Internal testing |
0.1.0-alpha.1 | 0.1.0-beta | Internal release. Release to more internal users for Beta testing. Not publically available. | Internal Beta testing |
0.1.0-beta | 0.1.0 | Released to internal users. | Internal release |
0.1.0 | 0.1.1 | Bug fix or patch. | Internal |
0.1.99 | 0.1.100 | Bug fix or patch. | Internal |
0.1.100 | 0.2.0 | New feature added to this internal version. | Internal |
0.2.0 | 0.2.1 | Bug fix or patch. | Internal |
0.2.1 | 0.2.2 | Bug fix or patch. | Internal |
0.2.2 | 0.3.0 | New feature added. | Internal |
0.3.5 | 1.0.0-alpha | Stable, but released to a limited number of external users. | Public (to limited user) |
1.0.0-alpha | 1.0.0 | Stable public release. | Public |
1.0.0 | 1.0.1 | Bug fix or security patch after the previous public release. | Public |
1.1.0 | 1.1.1 | Another bug fix or security patch. | Public |
1.1.50 | 1.1.51 | Bug fix or security patch. | Public |
1.1.51 | 1.2.0 | New feature added. | Public |
1.2.0 | 1.3.0 | New feature was added. | Public |
1.3.0 | 1.3.1 | Bug fix or security patch for existing implementation. | Public |
1.3.1 | 2.0.0 | Major update. Contains breaking change. Not compatible with the previous verison. | Public Major and breaking change. |
2.0.0 | 2.1.0 | New feature was added to the previous version. | Public |
NOTE
The above example indicates some version change status and what those changes mean.
Your release may or may not follow the exact same path, but it will be similar.
Scope of Update
When using these versions for our package manager, like for composer(composer.json), or npm(package.json), or any other package manager, then we can also define the scope of the update.
If we write an exact version then only that exact version is allowed.
Scope of update indicates, up to which version the package can be updated. The scope is indicated by adding a prefix to the version.
Tilda: Any Patch Version
Adding Tilda(~) as a prefix of SemVer indicates that, only the patch version is allowed for this package. Minor or mainor versions can not be changed.
Very useful for getting bug and security patches for the package. This gives more control(restriction) over the package update and leaves no scope of breaking already running application code.
Examples:
Package Version | Version Range | Description |
---|---|---|
~0.3.0 | >= 0.3.0 <0.4.0 | can be updated to 0.3.1, 0.3.2, 0.3.1000, 0.3.10012, etc. but not to 0.4.0 |
~1.1.2 | >=1.1.2 < 1.2.0 | we can update the package to version 1.1.3, 1.1.4, 1.1.10, 1.1.99, 1.1.100 etc. but not to 1.2.0 or 1.2.1 |
Caret: Any Minor Version
Adding Caret(^) as a prefix to any version, indicates to the package manager that only the Minor and Patch versions can be updated. The major version will be the same always.
Allowin the Minor version we will get the new features from the package.
Examples:
Package Version | Version Range | Description |
---|---|---|
^0.3.0 | >= 0.3.0 <1.0.0 | can be updated to 0.3.1, 0.3.2, 0.4.0, 0.4.1, 0.5.0, 0.5.1, 0.5.2, 0.5.100, etc. but not to 1.0.0 |
^1.1.2 | >=1.1.2 < 2.0.0 | we can update the package to version 1.1.3, 1.1.4, 1.1.10, 1.1.99, 1.1.100, 1.2.0, 1.2.1, 1.3.0, 1.4.0, 1.5.0, 1.5.1, 1.100.0, 1.100.1 etc. but not to 2.0.0, or 2.0.1 |
Comparison Operators(>, >=, <, <=, !=)
We can use comparison operators, like greater than(>), less than(<), greater than or equal(>=), and less than or equal(<=) to indicate the allowed version when updating or installing.
Comparison Operator | Example | Meaning |
---|---|---|
> | >1.2.1 | Any version higher than 1.2.1. But not including 1.2.1. |
< | <1.2.1 | Any version smaller than 1.2.1. But not including 1.2.1. |
>= | >=1.2.1 | Any version higher than or equal to 1.2.1. Version 1.2.1 is included in the allowed range. |
<= | <=1.2.1 | Any version smaller than or equal to 1.2.1. Version 1.2.1 is included in the allowed range. |
!= | !=1.2.4 | Any version is allowed, except 1.2.4. |
We can use logical and(&&) operator to combine multiple conditions-
Example | Version Constraint | Description |
---|---|---|
>=1.2.1 && <2.0.0 | >=1.2.1 <2.0.0 | Greater than or equal to 1.2.1, and less than 2.0.0. |
>1.2.1 && <2.0.0 | >1.2.1 <2.0.0 | Greater than to 1.2.1, and less than 2.0.0. |
>1.2.1 && !=1.4 | >1.2.1 !=1.4.x | Any version greater than 1.2.1. But versions 1.4.0, 1.4.1,1.4.x, etc. are not allowed. |
1.2.x && <2.0.0 | >=1.2.0 <2.0.0 | any patch version of 1.2 and which is less than 2.0.0. |
>1.2.1 && !=1.2.4 | >1.2.1 !=1.2.4 | any version greater than 1.2.1 but 1.2.4 is not allowed. |
1.0.1 – 1.9.0 && !=1.2.4 | >=1.0.1 <=1.9.0 !=1.2.4 | any version from 1.0.1 and 1.9.0. but specific version 1.2.4 is not allowed. |
Range with Hyphen(-)
We can decide the range with a hyphen(-) between the two versions. For example-
1.2.1 – 1.4.4 is equivalent to version >=1.2.1 and <=1.4.4
Asterisk(*) as Wildcard
We can use asterisk(*) in place of any part of the version number. For example-
1.2.* means any patch version is allowed.
1.* means any minor and patch version is allowed as long as the major version is 1.
Also, you can use the letter “x” for the same purpose.