When would you version a project with CalVer (a calendar-based number such as 24.04) instead of SemVer, and what do you give up by doing so?
answer
- one encodes compatibility, one encodes time
- who reads the number, and why
- support window versus dependency range
- resolvers cannot read a date
- artifact version is not API version
basics
~20 sCalVer encodes when a release was made; SemVer encodes whether it will break you. Choose CalVer for cadence-driven products with support windows and no dependency-resolver consumers — distributions, applications, data snapshots — and accept that the number carries no compatibility signal.
solid answer
~50 sThe two schemes answer different questions. SemVer answers "will upgrading break my build?"; CalVer answers "how old is this, and is it still supported?". CalVer fits artifacts released on a cadence where recency and the support window are the useful facts and where nobody resolves them through a dependency range — operating-system distributions like Ubuntu's `YY.MM`, desktop applications, IDEs, dataset or ruleset snapshots, and tools that intentionally never promise compatibility. It also solves a social problem: it removes the argument about whether a release "deserves" a major bump, and it makes staleness obvious at a glance. What you give up is the machine-readable compatibility claim. A resolver cannot infer from `24.04` to `24.10` whether anything broke, so consumers must pin exactly and read release notes. Rule of thumb: if other people's builds depend on you through a version range, use SemVer.
go deeper
Be able to say what CalVer is with one real example, such as Ubuntu 24.04 meaning April 2024, and state that it says nothing about whether an upgrade is compatible.
Explain the tradeoff in terms of who consumes the number: dependency resolvers need SemVer's compatibility claim, operators tracking support windows are better served by a date. Name the tooling cost of losing the patch/minor/major classification.
Show that you would decide by consumption model rather than taste, and mention the second-order effects — update-bot policies, exact pinning, and keeping the artifact version separate from the API contract version.
Own the scheme as policy across an organisation: which artifact classes use which scheme, how support windows are declared and enforced, and why re-versioning an existing published artifact is a one-way door you plan rather than improvise.
## Two schemes, two questions A version number is a compressed message. The scheme decides what it compresses. - **SemVer** compresses *compatibility*: `MAJOR.MINOR.PATCH` tells a consumer whether upgrading can break them. - **CalVer** compresses *time*: some combination of year, month, or day tells a consumer when the release was cut and, by extension, where it sits in a support window. Neither is more advanced than the other. They are appropriate to different consumption models. ## What CalVer looks like CalVer (calver.org) is a family, not one format. Common shapes are `YY.MM` (Ubuntu 24.04, released April 2024), `YYYY.MINOR` (JetBrains IDEs as 2024.1), and `YY.MINOR` (pip, which moved to a calendar scheme). Most CalVer projects keep a trailing serial or patch field so that a fix within a period is expressible: `24.04.1`. ## When CalVer is the right call 1. **The release cadence is the product.** A distribution that ships every six months with a defined support window is describing time, not API surface. `24.04 LTS` immediately tells an operator when support ends; `12.0.0` tells them nothing. 2. **There is no meaningful public API contract.** End-user applications, IDEs, CLI tools that consumers install rather than link against, and content snapshots (rulesets, vulnerability databases, geo-IP data) have no callers whose builds break on upgrade. 3. **Staleness is the risk you want visible.** A dependency last released as `19.10` is obviously old. `3.2.1` could have shipped yesterday or in 2016. 4. **You want to end the major-bump argument.** Teams burn real time debating whether a change "earns" a major. If nothing downstream resolves on the number, that debate produces no value, and CalVer removes it. ## What you lose The compatibility signal, and everything built on it. A dependency resolver reading `^24.04` has no basis for deciding whether `24.10` is safe, so consumers pin exactly and upgrade manually after reading notes. Ecosystem tooling assumes SemVer: automated dependency-update bots classify a bump as patch/minor/major to decide whether it can auto-merge, and under CalVer every bump looks the same, which usually means every bump is treated as risky. If your artifact is published to a package registry and consumed by other people's builds, that cost is normally decisive — use SemVer. A second, subtler cost: CalVer invites the assumption that releases are regular. If you adopt `YY.MM` and then skip two quarters, the scheme is actively misleading in a way `3.4.0` never would be. ## Hybrids and adjacent schemes Several projects mix the two deliberately: - **CalVer major, serial minor** — `2024.1`, `2024.2`: the year says how current, the serial orders releases within it. - **SemVer fields, calendar-derived major** — the major is bumped on a schedule rather than on breakage, so it doubles as a support-line identifier. - **Sequential/serial versioning** — a single incrementing integer (`build 4821`), which is really the honest scheme for internal services nobody depends on: it identifies a build and claims nothing else. A useful discipline is to keep the *artifact* version separate from the *API* version. A service can ship as `2024.31.4` while its HTTP contract is `v2`; the two change for different reasons and on different schedules, and conflating them is how teams end up unable to make an incompatible API change without an artifact major they don't want. ## How to decide, concretely Ask who reads the number and what decision they make with it: - **A dependency resolver in someone else's build** → SemVer, no exceptions worth taking. - **An operator deciding whether they are still supported** → CalVer, possibly with a support-window suffix like LTS. - **Only your own deployment pipeline** → a serial or commit-derived identifier is fine and more honest than either; the pipeline needs provenance, not a compatibility claim. The migration direction matters too. Moving from SemVer to CalVer is usually painless if consumers pin exactly, because calendar numbers keep increasing monotonically past the old ones. Moving from CalVer back to SemVer is painful: your version numbers are already high (`24.04`), so re-entering at `1.0.0` goes backwards and most resolvers will refuse to see it as an upgrade.
- Your internal service is deployed only by the team that owns it. What should its version number be?Something that identifies the build, not something that claims compatibility — a serial build number, a date-plus-serial, or the commit identifier. Nobody resolves it through a range, so SemVer's fields would be decoration and the major-bump debate pure overhead. What the pipeline actually needs is provenance: given a running instance, which commit and which build produced it.
- What breaks in the automated dependency-update ecosystem when a popular library switches to CalVer?Update bots and policies classify incoming bumps as patch, minor or major to decide what can merge unattended. Under CalVer every bump is unclassifiable, so consumers either auto-merge everything (risky) or nothing (stale). That is the main reason libraries published to package registries stay on SemVer even when their maintainers prefer calendar numbering.
- Can a project change from CalVer back to SemVer later?Technically yes, but it is awkward. CalVer numbers are large — after `24.04`, restarting at `1.0.0` looks like a downgrade and most resolvers will not offer it as an upgrade. The usual workaround is to keep climbing: continue from `25.0.0` and reinterpret the fields as SemVer, announcing the change loudly. Going the other direction, SemVer to CalVer, is far less disruptive.
saying these in an interview costs you the question
- Calling CalVer simply unprofessional or lazy
- Publishing a library on CalVer to a package registry
- Claiming CalVer conveys upgrade safety
- Assuming a date implies a support window automatically
- Merging the artifact version with the API contract version