Version number handling

A Collection of Interesting Ideas,

This version:
https://patrickkettner.github.io/quostibel/version-number-handling.html
Issue Tracking:
GitHub
Inline In Spec
Editor:
Patrick Kettner

Abstract

This specification defines the version and version_name manifest keys, the grammar of a version string, and the algorithm for comparing two version strings.

Key version

The value must be a non-empty string.

Should this specification require Chrome’s strict grammar for version, or scope the key to the loosest grammar all three already accept without a warning?

Grammar accepted today:

Tracked at w3c/webextensions#283.

Key version_name

An optional string providing a version to show to users in place of version, for example to include a channel qualifier such as "1.2 beta". It has no effect on version comparison and is not required to follow the version string grammar. The key is OPTIONAL, and an implementation MAY ignore it.

Firefox does not implement version_name as a manifest key. This makes version_name a two-of-three feature: Chrome and Safari support it as display text that falls back to version when absent or empty. Firefox has stated the omission is deliberate, not an oversight: bugzilla 1380219, RESOLVED WONTFIX, records the decision, reasoning that the version string is part of an extension’s identity and a customizable display string risks confusing users.

1. Version number handling

1.1. The version string

An extension’s version string is the value of its version manifest key.

To parse a version string given input:

  1. Let parts be the result of strictly splitting input on U+002E (.).

  2. If parts contains the empty string, return failure.

  3. Let components be an empty list.

  4. For each part of parts:

    1. If part does not consist entirely of ASCII digits, return failure.

    2. If part’s length is greater than 1 and part’s first code point is U+0030 (0), return failure.

    3. Append the result of interpreting part as a base-ten integer to components.

  5. Return components.

"1.2.3" parses to «1, 2, 3». "01.2" and "1..2" both fail to parse.

Firefox and Safari accept a version string that fails this algorithm, storing the value unchanged.

1.2. Comparing version strings

To compare two version strings given versionA and versionB:

  1. Let a be the result of parsing versionA.

  2. Let b be the result of parsing versionB.

  3. If a or b is failure, return failure.

  4. Let n be the larger of a’s and b’s size.

  5. For each i in the range 0 to n, exclusive:

    1. Let x be a[i] if i is less than a’s size, otherwise 0.

    2. Let y be b[i] if i is less than b’s size, otherwise 0.

    3. If x is greater than y, return "versionA is newer".

    4. If x is less than y, return "versionB is newer".

  6. Return "equal".

This algorithm returns failure when either input does not parse. What a user agent does with that failure is a consequence of § 1.3 Invalid version strings, not of this algorithm.
Comparing "1.2" and "1.2.0" returns "equal": the missing third component of "1.2" is treated as 0.
"4294967295.0" and "1.0" both parse successfully under Chrome’s grammar and under Firefox’s (Firefox only warns about the 10-digit first component; it does not reject it). Chrome and Firefox order them oppositely:

Chrome and Firefox disagree about which of "4294967295.0" and "1.0" is newer, for two version strings both accept without error.

Should this specification require one version-comparison algorithm, permit either of the two in use today, or leave comparison implementation-defined and unobservable to extensions?

Chrome’s comparator performs the numeric tuple compare given above. Firefox and Safari:

1.3. Invalid version strings

A version string that does not parse is invalid. Chrome, Firefox, and Safari each treat an invalid or empty version differently from an absent key.

Must an implementation reject an extension whose version is invalid, and if so, is the whole extension rejected, or only the key?

The consequence today, including for the specific case of an empty version, which the normative requirement above (Key version) already forbids:

1.4. Observability to extensions

Version comparison is not exposed to extension JavaScript as an API in any of the three browsers examined; it is purely an install/update-time concern of the browser.

runtime.getManifest() returns the version string exactly as authored, unmodified, in Chrome, Firefox, and Safari: it reads directly from the parsed manifest object rather than from any canonicalized form.

runtime.getVersion() is a required method (w3c/webextensions#878, closed 2026-04-08). Whether it returns the literal manifest string or a canonicalized form is implementation-defined. Chrome canonicalizes its input before returning it, so calling it can return a string different from runtime.getManifest().version for the same extension (for example "1.002.3" in the manifest becomes "1.2.3" from getVersion()); Safari performs no canonicalization, so the two calls always agree. Firefox does not implement runtime.getVersion() yet.

Conformance

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119

Issues Index

Should this specification require Chrome’s strict grammar for version, or scope the key to the loosest grammar all three already accept without a warning?

Grammar accepted today:

Tracked at w3c/webextensions#283.

↵

Firefox and Safari accept a version string that fails this algorithm, storing the value unchanged.

↵
Should this specification require one version-comparison algorithm, permit either of the two in use today, or leave comparison implementation-defined and unobservable to extensions?

Chrome’s comparator performs the numeric tuple compare given above. Firefox and Safari:

↵
Must an implementation reject an extension whose version is invalid, and if so, is the whole extension rejected, or only the key?

The consequence today, including for the specific case of an empty version, which the normative requirement above (Key version) already forbids:

↵