Klor.

Update gating

Telling old builds to update. iOS and Android only, web apps reload on their own.

The two thresholds

Per platform, per environment, you set a floor and a target.

minSupportedVersionstring

Below this, the verdict is forced. The build is considered unusable.

latestVersionstring

Below this but at or above the minimum, the verdict is optional. There is something newer, but this build still works.

A minimum above the latest version is refused. It would force people onto a build that is itself below the floor, a prompt with no way out.

Blocked builds

A floor says “anything this old is unsupported”. A blocked build says “2.3.1 in particular is broken”, and forces an update off that one version even though it clears the floor. This is the lever to reach for during an incident.

Version strings

Klor is more permissive than strict semver, because real app versions are not strict semver. Leading numeric segments are compared element-wise with missing parts treated as zero, so 2.4 equals 2.4.0, four-part Android builds like 2.4.0.1187 compare correctly, and 2.10.0 beats 2.9.0. A leading v and +build metadata are ignored.

A version Klor cannot parse produces no prompt at all. Failing open is deliberate: locking every user out because a version string was malformed is far worse than missing one update prompt.

Rendering the prompt

Klor returns the verdict, the store URL, and your copy. Nothing is rendered for you, so the prompt matches your app rather than looking like someone else’s SDK.

const gate = useVersionGate()

// gate.status 'none' | 'optional' | 'forced'
// gate.reason 'none' | 'blocked' | 'belowMinimum' | 'behindLatest' | 'notReady'
// gate.message the copy you wrote for that case
// gate.storeUrl, gate.latestVersion, gate.currentVersion