1---
2title: Runtime versions and updates
3sidebar_title: Runtime versions
4description: Learn about different runtime version policies and how they may suite your project.
5---
6
7import ImageSpotlight from '~/components/plugins/ImageSpotlight';
8
9Runtime versions are a property that guarantees compatibility between a build's native code and an update. When a project is made into a build, the build will contain some native code that cannot be changed with an update. Therefore, an update must be compatible with a build's native code to run on the build.
10
11To illustrate how builds and updates interact, take a look at the following diagram:
12
13<ImageSpotlight alt="Native and update layers diagram" src="/static/images/eas-update/layers.png" />
14
15Builds can be thought of as two layers: a native layer that's built into the app's binary, and an update layer, that is swappable with other compatible updates. This separation allows us to ship bug fixes to builds as long as the update with the bug fix can run on the native layer inside the build. The `"runtimeVersion"` property allows us to guarantee that an update is compatible with a specific build's native code.
16
17Since updates must be compatible with a build's native code, any time native code is updated, we're required to make a new build before publishing an update. Some developers only update native code when upgrading to a new Expo SDK, while others may upgrade native code between builds or at other intervals. Below is an explanation of different situations and configurations that may suite your project.
18
19## Setting `"runtimeVersion"`
20
21To make managing the `"runtimeVersion"` property easier between builds and updates, we've created runtime version policies that will update automatically based on other fields inside the app config (**app.json**/**app.config.js**). If these policies do not match the development flow of a project, there's also an option to set the `"runtimeVersion"` manually.
22
23### `"sdkVersion"` runtime version policy
24
25By default, we provide the `"sdkVersion"` runtime version policy after running `eas update:configure`:
26
27```json
28{
29  "expo": {
30    "runtimeVersion": {
31      "policy": "sdkVersion"
32    }
33  }
34}
35```
36
37The `"sdkVersion"` policy will set the runtime version to the current SDK version of a project. For instance, if the project is on Expo SDK 1.0.0, the runtime version with this policy will be `"exposdk:1.0.0"`. This runtime version will update any time we update the project's Expo SDK. So, if we ran `expo upgrade` and installed Expo SDK 2.0.0, then the runtime version would become `"exposdk:2.0.0"`.
38
39This runtime version policy is perfect if you are not including custom native code in your project and the only native changes you make are when upgrading Expo SDKs.
40
41### `"appVersion"` runtime version policy (available in SDK 46 and higher)
42
43We provide the `"appVersion"` runtime version policy for projects that have custom native code that may change between builds:
44
45```json
46{
47  "expo": {
48    "runtimeVersion": {
49      "policy": "appVersion"
50    }
51  }
52}
53```
54
55For a project that has the following in its app config:
56
57```json
58{
59  "expo": {
60    "runtimeVersion": {
61      "policy": "appVersion"
62    },
63    "version": "1.0.0",
64    "ios": {
65      "buildNumber": "1"
66    },
67    "android": {
68      "versionCode": 1
69    }
70  }
71}
72```
73
74The `"appVersion"` policy will set the runtime version to the project's current `"version"` property. The runtime version for the Android and iOS builds and any updates would be in this case `"1.0.0"`.
75
76This policy is great for projects that contain custom native code and that update the `"version"` field after every public release. To submit an app, the app stores require an updated native version number for each submitted build, which makes this policy convenient if you want to be sure that every version installed on user devices has a different runtime version.
77
78When using this policy, you need to manually update `"version"` field in app config every time there is a public release, but for Play Store's Internal Test Track and the App Store's TestFlight uploads, you can rely on `"autoIncrement"` option in **eas.json** to [manage versions for you](../build-reference/app-versions/#remote-version-source).
79
80### `"nativeVersion"` runtime version policy
81
82We provide the `"nativeVersion"` runtime version policy for projects that have custom native code that may change between builds:
83
84```json
85{
86  "expo": {
87    "runtimeVersion": {
88      "policy": "nativeVersion"
89    }
90  }
91}
92```
93
94The `"nativeVersion"` policy will set the runtime version to the project's current `"version"` and `"buildNumber"` (iOS) or `"versionCode"` (Android) properties. For a project that has the following in its app config:
95
96```json
97{
98  "expo": {
99    "runtimeVersion": {
100      "policy": "nativeVersion"
101    },
102    "version": "1.0.0",
103    "ios": {
104      "buildNumber": "1"
105    },
106    "android": {
107      "versionCode": 1
108    }
109  }
110}
111```
112
113The runtime version for the Android and iOS builds and any updates would be the combination of `"[version]([buildNumber|versionCode])"`, which in this case would be `"1.0.0(1)"`.
114
115This policy is great for projects that contain custom native code and that update the native version numbers (`"buildNumber"` for iOS and `"versionCode"` for Android) for each build. To submit an app, the app stores require an updated native version number for each submitted build, which makes this policy convenient if you want to be sure that every app uploaded to the Play Store's Internal Test Track and the App Store's TestFlight distribution tools has a different `runtimeVersion`.
116
117It's important to know that this policy does require the developer to manage the native version numbers manually between each build.
118
119Also, if you select a different native version between Android and iOS, you'll end up with builds and updates with separate runtime versions. When you publish an update, EAS CLI will detect that two updates are needed, and it will create two updates with the required runtime versions and publish them separately.
120
121### `"fingerprintExperimental"` runtime version policy (experimental)
122
123We provide the `"fingerprintExperimental"` runtime version policy for a project that has custom native code that may change between builds:
124
125```json
126{
127  "expo": {
128    "runtimeVersion": {
129      "policy": "fingerprintExperimental"
130    }
131  }
132}
133```
134
135This policy is well-suited for projects incorporating custom native code that require safe updates without native conflicts. Unlike the `"nativeVersion"` policy, the `"fingerprintExperimental"` option automatically scans your project's native dependencies to update the `"runtimeVersion"` accordingly.
136
137Enabling fingerprinting may lengthen build times, as the fingerprinting process can be resource-intensive.
138
139> **warning** Using the experimental `fingerprintExperimental` runtime policy may result in unexpected system behavior. This policy is still under active development as part of the `@expo/fingerprint` beta package, and its specifications may change in the future.
140
141### Custom `"runtimeVersion"`
142
143You can also set a custom runtime version that meets the [runtime version formatting requirements](/versions/latest/config/app/#runtimeversion):
144
145```json
146{
147  "expo": {
148    "runtimeVersion": "1.0.0"
149  }
150}
151```
152
153This option is good for developers who want to manage the runtime version manually, separately from any other version numbers present in a project's app config. It gives the developer complete control over which updates are compatible with which builds.
154
155### Platform specific `"runtimeVersion"`
156
157You can also set a runtime version for a specific platform:
158
159```json
160{
161  "expo": {
162    "android": {
163      "runtimeVersion": "1.0.0"
164    }
165  }
166}
167```
168
169When both a top level runtime and a platform specific runtime are set, the platform specific one takes precedence.
170
171## Avoiding crashes with incompatible updates
172
173The main issue that can arise when publishing updates is that the update could rely on native code that the build it's running on does not support. For instance, imagine we made a build with a runtime version of `"1.0.0"`. Then, we submitted that build to the app stores and released it to the public.
174
175Later on, imagine that we developed an update that relied on a newly installed native library, like the `expo-in-app-purchases` library, and we did not update the `"runtimeVersion"` property, so that it is still `"1.0.0"`. If we published an update, the builds with the `"runtimeVersion"` of `"1.0.0"` would think the incoming update with the same runtime version was compatible and it would attempt to load the update. Since the update would make calls to code that does not exist inside the build, the app would crash.
176
177There are a few ways to avoid crashes like this:
178
179- Whenever we install or update native code, iterate the `"runtimeVersion"` property in the project's app config (**app.json**/**app.config.js**).
180- Create a preview build of your app and load it on a test device. Then, publish the update to the "preview" branch to make sure it works as expected before publishing it to the project's production branch.
181
182If this error does occur, then you can republish a previous known-good update, then ask users to delete the app and reinstall it.
183
184In the future, the `expo-updates` library will prevent many instances of this from crashing the app. If we can detect this particular issue, we'll automatically roll back to a previous update instead of loading the bad update.
185