In an Expo project, how do you raise the Android minSdkVersion for a maps SDK without editing build.gradle, and where does the value land?
answer
- a dedicated build-values plugin
- android.minSdkVersion option
- written to gradle.properties
- iOS: Podfile.properties.json
- schema check and version floors
basics
~10 sAdd ["expo-build-properties", { "android": { "minSdkVersion": 26 } }] to plugins and re-run prebuild. The plugin writes android.minSdkVersion into android/gradle.properties, which the generated Gradle build reads.
solid answer
~30 sI add `expo-build-properties` to `plugins` as `["expo-build-properties", { "android": { "minSdkVersion": 26 } }]`. At prebuild it writes `android.minSdkVersion` into `android/gradle.properties`, which the generated Gradle build reads; most iOS options go into `ios/Podfile.properties.json`. It also covers `compileSdkVersion`, `targetSdkVersion`, `kotlinVersion`, R8 via `enableMinifyInReleaseBuilds`, `extraMavenRepos`, and on iOS `useFrameworks` and `extraPods`. Options are schema-validated and versions below the plugin's floor throw. Editing `build.gradle` in a CNG project is lost at the next clean prebuild. Raising the floor drops devices below that API level, and since SDK 56 the iOS deployment target belongs in the app config's own `ios.deploymentTarget`.
code
json · 18 lines{
"expo": {
"plugins": [
[
"expo-build-properties",
{
"android": {
"minSdkVersion": 26,
"extraMavenRepos": ["https://maven.example.com/releases"]
},
"ios": {
"useFrameworks": "static"
}
}
]
]
}
}go deeper
Recall that native build values like minSdkVersion are set through the expo-build-properties plugin, not by editing Gradle files.
Explain where the plugin writes each platform's values, which options it covers, and that it needs prebuild plus a rebuild.
Weigh the consequences: raising the floor drops older devices, one value serves every library, and duplicate owners of the property must be removed.
Own the platform-support policy: which API levels and iOS versions the product supports, and how library requirements are allowed to raise them.
## What `expo-build-properties` is In a React Native Android project, values such as `minSdkVersion`, `compileSdkVersion` and `targetSdkVersion` live in the Gradle build. In an Expo project using **Continuous Native Generation**, you do not edit those files: prebuild regenerates them. **`expo-build-properties`** is the config plugin that lets the app config override these native build values. For a delivery app adding a maps SDK that requires a higher minimum Android API level than the project's default, the change is one plugin entry: ```json { "expo": { "plugins": [ ["expo-build-properties", { "android": { "minSdkVersion": 26 } }] ] } } ``` ## Where the value goes The plugin does not rewrite Gradle code directly. On Android it writes **properties** into `android/gradle.properties`, such as `android.minSdkVersion`, which the generated Gradle build reads. On iOS, most of its settings go into `ios/Podfile.properties.json`, which the generated `Podfile` reads. | Option | Platform | Effect | |---|---|---| | `minSdkVersion` | Android | Lowest Android API level that can install the app | | `compileSdkVersion` | Android | SDK the app is compiled against | | `targetSdkVersion` | Android | API level whose behaviour the app opts into | | `kotlinVersion` | Android | Kotlin version used to build | | `enableMinifyInReleaseBuilds` | Android | Turns on R8 code shrinking in release | | `extraMavenRepos` | Android | Adds Maven repositories, e.g. for a vendor SDK | | `useFrameworks` | iOS | `static` or `dynamic` frameworks for CocoaPods | | `extraPods` | iOS | Adds CocoaPods dependencies | ## Validation and version floors The plugin validates its options against a schema before applying them, and it enforces **minimum versions**: a `minSdkVersion` or other version below the floor it supports throws an error that names the setting and the minimum. Two version notes for Expo SDK 57: - The plugin's `ios.deploymentTarget` option is **deprecated**; since SDK 56 the app config has a built-in `ios.deploymentTarget` property instead. - `android.newArchEnabled` and `ios.newArchEnabled` were **removed**, because the New Architecture is the only architecture. ## Applying the change A plugin option only takes effect when the native project is regenerated and rebuilt: 1. Edit the `expo-build-properties` entry in the app config. 2. Regenerate: `npx expo prebuild --clean`, or let EAS Build run prebuild for a project without committed native folders. 3. Build a new binary, including a new development build for the team. ## Consequences of raising `minSdkVersion` Raising the floor is not free, and an interviewer will ask about it: - **Devices below the new API level can no longer install the app**, including updates to it. Check how many active users sit below it first. - **It is one value for the whole app.** The highest requirement among your libraries sets it; lowering it later below what a library needs breaks the build. - **Keep one owner.** If a library's own plugin also writes `android.minSdkVersion`, two plugins now write the same property. Remove the duplicate rather than depend on plugin order. ## Checking the result 1. After `npx expo prebuild --clean`, open `android/gradle.properties` and confirm the `android.minSdkVersion` line carries the new value. 2. Build the Android app. If some library still needs a higher floor than the project declares, the Android build fails with an error naming both values, which tells you the real minimum. 3. Run the app on the oldest device or emulator you still support, to confirm the maps screen works at the new floor. 4. Record the reason for the value next to it, in an `app.config.ts` comment or the change description, so nobody lowers it later. ## Why not edit `build.gradle`? - In a CNG project, `npx expo prebuild --clean` deletes and regenerates the `android` folder, so a hand edit is lost. - EAS Build runs prebuild on a clean checkout, so the edit never reaches CI if the folders are not committed. - The app config is reviewable in one place; a teammate can see why the floor is 26 without opening native files. If the project has committed native folders (a bare workflow), you edit Gradle directly, and `expo-build-properties` is not the tool. These option names and behaviours are from `expo-build-properties` 57.x in Expo SDK 57, on React Native 0.86.
- In Expo SDK 57, where should the iOS deployment target be set?In the app config's built-in `ios.deploymentTarget` property. `expo-build-properties` still accepts an `ios.deploymentTarget` option, but it is deprecated since SDK 56 in favour of the built-in field. Setting it in one place avoids two sources of truth for the same native value.
- What does expo-build-properties do if minSdkVersion is set below the version it supports?It throws during config evaluation with a message naming the setting and the minimum it needs to be, so prebuild stops before generating a broken project. The same check exists for the iOS deployment target. Values also pass through a schema, so a wrong type, such as a string where a number is expected, fails early too.
saying these in an interview costs you the question
- Edit android/app/build.gradle directly in a CNG project
- expo-build-properties changes apply without re-running prebuild
- Raising minSdkVersion has no effect on who can install
- Set newArchEnabled in expo-build-properties in SDK 57
- The iOS values also go into gradle.properties