TS-11: Versioning
Software components that are released, distributed, or otherwise consumed by other parties — including libraries, web services, end-user applications, command-line tools, and infrastructure modules — SHOULD use a consistent versioning scheme for their releases. This makes it easier to manage compatibility between components and to communicate changes to consumers.
Choosing a versioning scheme
The two versioning schemes covered in this standard — semantic versioning (SemVer) and calendar versioning (CalVer) — are suited to different types of software:
- SemVer is RECOMMENDED for software with a stable, contractual interface that consumers depend on: libraries, public APIs, and SDKs. The semantic increments (major, minor, patch) communicate compatibility precisely.
- CalVer is RECOMMENDED for software where time-of-release is the most meaningful identifier and where backwards-compatibility commitments are softer: end-user applications, internal services, infrastructure modules, command-line tools, and continuously-deployed software (see TS-10: Releasing).
When SemVer would technically apply but the surface area of the "public API" is fuzzy or shifting (eg. end-user GUIs, where "breaking change" is hard to define), prefer CalVer.
A single version string SHOULD use one scheme consistently. However, the two schemes MAY be layered for different audiences within the same project — for example, SemVer for internal versioning (used by developers and dependency managers) and CalVer for public release identifiers (used in marketing and end-user communication). Where layered schemes are used, both identifiers MUST be unambiguously mapped to the same source-control tag and artifact, so the binding remains traceable.
Semantic versioning
It is RECOMMENDED to use the Semantic Versioning 2.0.0 scheme for versioning software components. This is a widely adopted standard.
Semantic version numbers follow this format:
v{major}.{minor}.{patch}- <major>: Increment this number by 1 when the release includes incompatible or breaking API changes. For user-facing GUIs, a breaking change could be considered to be a change in the behavior of an existing UI control, or removal of existing controls.
- <minor>: Increment this number by 1 when the release includes user-facing changes that do not break backwards compatibility — new features, bug fixes, and runtime-quality improvements.
- <patch>: Increment this number by 1 when the release includes only internal changes that do not affect the user-visible contract — refactors, formatting changes, maintenance, and chores.
The following is a representative chronology of semantic version number progressions:
v1.0.0v1.1.0v1.2.0v1.2.1v2.0.0v2.0.1v2.0.2v2.1.0
Bumping versions from commit history
The mapping between SemVer increments and the commit conventions defined in TS-9: Version Control is as follows:
- Commits flagged
BREAKINGtrigger a major bump. - Commits of type
feature,fix, orruntime(withoutBREAKING) trigger a minor bump. These are the user-facing changes that the version number communicates to consumers. - Commits of type
refactor,format,maintenance, orchore(withoutBREAKING) trigger a patch bump. These are internal changes that affect the codebase but not the user-visible contract. - Commits flagged
INCOMPAT(internal-only breaking changes) MUST NOT, on their own, trigger a major bump — they affect internal callers but not the public API contract, and so they bump patch like any other internal change. - Commits of type
step,release,merge, andrevertare version-neutral; they do not trigger bumps.
When a release accumulates multiple commits, the highest applicable bump wins: BREAKING beats feature/fix/runtime beats refactor/format/maintenance/chore.
Tools such as semantic-release and release-please can be configured to
follow this mapping automatically. Manual version selection MUST follow the same
rules.
Experimental features
Features that are clearly marked as "experimental", and that require users to explicitly opt-in to use them, MAY be subsequently changed, modified significantly, or removed in a breaking way without triggering a major version bump. The experimental status serves as an explicit contract that API stability is not guaranteed.
Experimental features MUST be documented as such, clearly visible to users who discover them, and their unstable status MUST be communicated in release notes.
Once an experimental feature becomes stable and is no longer marked as experimental, the usual SemVer rules apply – breaking changes to that feature then require a major version bump.
Calendar versioning
Semantic versioning is the RECOMMENDED default, but it is not the only viable scheme. Calendar versioning (CalVer) — where version strings encode dates rather than semantic increments — is well-suited to projects with regular release cadences and to software where backwards-compatibility commitments are not the central concern.
Common CalVer formats include YYYY.MM.DD, YYYY.MM, YY.0M.MICRO, and
YYYY.MINOR.PATCH. Examples: 2025.07.14, 25.07, 2026.0.1. The choice of
granularity depends on release frequency.
CalVer is often appropriate for:
- Software with continuous deployment, where individual SemVer-style increments are too granular to be informative (see TS-10: Releasing).
- Time-boxed releases where the date itself is the most meaningful identifier
(eg. Ubuntu’s
YY.MMreleases). - Internal tools, infrastructure components, and operating-system-style projects without a consumer-facing API contract.
CalVer SHOULD NOT be combined with SemVer increments in the same string (eg.
1.2.3-2025.07), as this defeats the purpose of both schemes. A project SHOULD
pick one and apply it consistently.
All other guidance in this standard — tagging conventions, the v prefix, build
metadata, pre-release suffixes — applies equally to CalVer schemes.
Tagging
Each release MUST be marked in version control by an annotated Git tag whose
name is the version string prefixed with v. For example, version 1.2.3 is
tagged v1.2.3. The v prefix is part of the tag convention, not the version
string itself — published version strings (in package metadata, release notes,
etc.) MAY omit it.
Tags MUST be annotated (git tag -a), so they carry a tagger, timestamp, and
message. Tags SHOULD be signed (git tag -s) where commit signing is in use;
see TS-9: Version Control.
Tags MUST be permanent. Once pushed to the reference repository, a tag MUST NOT be deleted, moved, or recreated against a different commit. If a release is botched, cut a new release with a new version number rather than retagging.
The tag and the artifacts produced from it MUST share the same identifier — eg.
if v1.2.3 is the tag in the source repository, v1.2.3 is also the identifier
under which the corresponding compiled artifacts are stored in the artifact
repository (see TS-9: Version Control).
Tag a release as soon as possible after the integration that completes it,
ideally as part of the automated pipeline that promotes commits to the release
trunk. Tags are the canonical record of versioned releases — merge commits
indicate when changes were integrated, but only tags identify which version
corresponds to a given commit.
Tip
For longer release notes, the -F option reads the tag message from a file:
git tag -a v1.2.3 -F RELEASE_NOTES.md. To push commits and any annotated tags
reachable from the pushed commits in a single operation, use
git push --follow-tags.
Version zero
v0.x.x releases are NOT REQUIRED to comply with the Semantic Versioning rules.
Version zero releases SHOULD be used to preview, pre-release, or prototype builds of new software. These releases are considered to be unstable and not production-grade. Breaking changes MAY be introduced to version zero releases without bumping then major version number.
Pre-release versions
For pre-release versions, the semantic version number SHOULD be followed by a hyphen and then a stage identifier, followed by a dot and then a zero-indexed incrementing integer.
v{major}.{minor}.{patch}-{stage}.{inc}Common stage identifiers include:
alpha— early, unstable, feature-incomplete builds.beta— feature-complete but possibly buggy preview builds.rc— release candidates expected to be stable and unlikely to change before final release.canary— automated nightly or per-commit builds, used for early integration testing.dev— single-revision builds used for testing through the registry.next— sometimes used in place ofbetaorrcto identify the upcoming version.
The choice of identifier depends on the project’s release pipeline and ecosystem conventions.
Example of a release order, top-to-bottom
v1.0.0-alpha.0 v1.0.0-alpha.1 v1.0.0-alpha.2 v1.0.0-beta.0 v1.0.0-beta.1 v1.0.0 v1.1.0-alpha.0 v1.1.0-alpha.1 v1.1.0-beta.0 v1.1.0
This is an extension of the Semantic Versioning standard and is based on the convention used by the NPM registry of JavaScript packages. This convention may need to be adapted for other package managers and software ecosystems.
Distribution channel tags — such as latest, stable, next, or lts,
assigned by package managers to point to specific versions — are a related but
distinct concept. They are not part of the version string itself; they are
metadata maintained externally by the registry. Consult your package manager’s
documentation for how distribution channels are configured.
Build metadata
SemVer 2.0.0 supports an OPTIONAL build metadata suffix, separated from the
version (or pre-release) by a +:
v{major}.{minor}.{patch}[-{prerelease}][+{build-metadata}]Examples: v1.2.3+sha.5114f85, v1.0.0-rc.1+20251201.
Build metadata MUST NOT affect version precedence — 1.2.3+a and 1.2.3+b are
considered the same version. It is intended for embedding
non-version-determining build context: commit SHAs, build numbers, build dates,
or CI run identifiers.
Build metadata is OPTIONAL but RECOMMENDED in contexts where the source-tag-to-artifact binding needs to be made explicit in the version string itself — such as continuous deployment pipelines where artifact identifiers are not separately tracked. See the Tagging section above.
LTS releases
For long-term support releases, " LTS" MAY be appended to the version number.
v1.0.0v1.1.0v1.2.0v1.3.0 LTSv1.4.0v1.5.0v2.0.0v2.1.0 LTSv2.2.0
Named releases
In addition to a version number, consumer-friendly release names such as "Autumn 2025" MAY be used for user-facing software applications.