Targeting by Expo runtime
The SDK reads the device’s runtime once and sends it with every sync. Rules are compiled into the snapshot and matched on the phone, so targeting works offline.
What the device reports
| Field | Source | Notes |
|---|---|---|
platform | React Native Platform.OS | "ios" or "android". |
applicationId | expo-application | iOS bundle identifier or Android application id. Shown in Project settings → Connected apps. |
appVersion | expo-application nativeApplicationVersion | The store version, e.g. 2.4.1. |
buildVersion | expo-application nativeBuildVersion | The build number, e.g. 83. |
runtimeVersion | expo-updates | Which OTA updates the binary can run. |
updateId | expo-updates | The OTA update currently running, or null. |
isEmbeddedLaunch | expo-updates | true for the bundle embedded in the binary, false for an OTA update, null when expo-updates is disabled. Reported, not targetable. |
Attributes a rule can match
| Attribute | Operators | Comparison |
|---|---|---|
platform | eq, neq | String equality. |
appVersion | eq, neq, gte, lte | Real version comparison, never lexicographic (below). |
buildVersion | eq, neq, gte, lte | Numeric when both sides are integers, otherwise string order. |
runtimeVersion | eq, neq | Equality only in v0; runtime versions are not guaranteed to be semver. |
updateId | eq, neq | Equality. |
user.id | eq, neq | The identified user. |
user.<trait> | eq, neq | Any trait passed to identify, compared as a string. |
audience | eq, neq | Membership of a saved audience. See People. |
All conditions in a rule AND together. Rules are tried in priority order and the first whose conditions all match decides.
A missing attribute never matches, except for neq: “not equal to X” is true of a device that has no value at all. gte and lte on an attribute that is not ordered behave as equality.
How appVersion compares
- Numeric dot-segments compare numerically:
2.10.0is greater than2.9.0. - Missing segments read as zero:
2.4equals2.4.0. - A pre-release suffix sorts before the release it precedes:
2.4.0-beta.1is less than2.4.0. - A leading
vis ignored. Anything unparsable falls back to a plain string comparison rather than throwing inside evaluation.
Example
Ship a feature only to iOS users on the 2.4 line who are running an OTA update, not the embedded bundle you cannot patch: