skip to content

What does minSdk = flutter.minSdkVersion mean in a Flutter app's build.gradle.kts, and when should you replace it with a fixed number?

level: middleimportance: should knowfreq 32%

answer

  1. value supplied by the Flutter Gradle plugin
  2. moves with Flutter upgrades
  3. plugin needs a higher minimum
  4. raising it drops older devices
  5. hard-coded too-low values get migrated

basics

~20 s

flutter.minSdkVersion is the minimum Android API level the Flutter SDK supplies through its Gradle plugin, 24 in Flutter 3.47. Replace it with a higher fixed number when a plugin requires one, or pin it to stop upgrades moving it.

solid answer

~40 s

A new Flutter project's `defaultConfig` sets `minSdk = flutter.minSdkVersion`, `targetSdk = flutter.targetSdkVersion` and `compileSdk = flutter.compileSdkVersion`, values from the Flutter Gradle plugin's `FlutterExtension` — 24, 36 and 36 in Flutter 3.47. Keeping the variable means the minimum follows each Flutter release. You set a literal such as `minSdk = 26` when a plugin declares a higher minimum: the build then fails with a manifest-merger error that `flutter` turns into a message naming the plugin and the value to set. Raising it excludes devices below that API level. Going below Flutter's minimum is not supported; the tool's migrator rewrites hard-coded values from 16 to 23 back to `flutter.minSdkVersion`.

code

kotlin · 13 lines
kotlin
android {
    namespace = "com.example.plantcare"
    compileSdk = flutter.compileSdkVersion

    defaultConfig {
        applicationId = "com.example.plantcare"
        // The soil-sensor plugin declares minSdk 26.
        minSdk = 26
        targetSdk = flutter.targetSdkVersion
        versionCode = flutter.versionCode
        versionName = flutter.versionName
    }
}

go deeper

for a junior

Know that minSdk sets the oldest Android version the app installs on, and that flutter.minSdkVersion is Flutter's supported default.

for a middle

Explain where the flutter extension values come from, how a plugin's higher minimum surfaces as a build error, and how to override it.

for a senior

Decide between following Flutter's default and pinning, check device reach before raising, and keep targetSdk raises tested.

for a principal

Set the supported-device policy: which Android versions the product commits to, and how that interacts with plugin choices and Flutter upgrades.

## Where the value comes from Android apps declare three SDK levels in `android/app/build.gradle.kts`: - **`minSdk`** — the lowest Android API level the app installs on; - **`targetSdk`** — the API level the app is designed and tested against, which changes some platform behaviours; - **`compileSdk`** — the Android SDK version the code is compiled against. A Flutter project does not hard-code them. The template writes: ```kotlin android { compileSdk = flutter.compileSdkVersion defaultConfig { minSdk = flutter.minSdkVersion targetSdk = flutter.targetSdkVersion } } ``` `flutter` here is the **`FlutterExtension`** registered by the Flutter Gradle plugin (`dev.flutter.flutter-gradle-plugin`). In Flutter 3.47 it supplies: | Property | Value in Flutter 3.47 | |---|---| | `flutter.minSdkVersion` | 24 | | `flutter.compileSdkVersion` | 36 | | `flutter.targetSdkVersion` | 36 | These are the values the Flutter team supports and tests the engine against. Some older documentation pages still quote lower minimums; the tool's source is the current truth. ## Keeping the variable With the variable in place, **upgrading Flutter moves the minimum** automatically when the framework drops support for an Android version. For most apps that is what you want: the app always builds with a supported configuration. ## When to write a literal 1. **A plugin needs a higher minimum.** Android's manifest merger fails the build with `uses-sdk:minSdkVersion 24 cannot be smaller than version 26 declared in library [...]`. The Flutter tool recognises this error and prints a box naming the plugin, suggesting the `minSdkVersion` to set, and warning that the app will no longer be available to users below that level. You then set `minSdk = 26` — or look for a plugin version that supports lower levels. 2. **You want upgrades not to move it.** Pinning a literal equal to the current value keeps the supported-device range stable across Flutter upgrades, at the cost of noticing yourself when Flutter's minimum rises above it. For a plant-care app whose soil-sensor plugin needs API 26, `minSdk = 26` is the honest setting: devices below 26 could not use the core feature anyway. ## What you cannot do You cannot meaningfully set `minSdk` **below** Flutter's supported minimum — the engine is not built or tested for those devices. The Flutter tool even includes a **migration** that rewrites hard-coded `minSdk` values from 16 to 23 in an app's Gradle file back to `flutter.minSdkVersion`, so old projects stop declaring unsupported levels. ## `targetSdk` is different `targetSdk` is about behaviour, not reach: raising it opts the app into newer platform rules (permissions, background limits). Google Play sets deadlines by which updates must target a recent API level; those store rules are a separate topic. Keeping `flutter.targetSdkVersion` generally tracks a recent level, but a raised target still needs testing, because behaviour changes affect plugins and native code. ## Checking the impact - **Reach**: check the store's device statistics for how many active installs a new minimum would exclude before you raise it. - **Plugins**: each plugin's Android `build.gradle` declares its own `minSdk`; the highest one wins at merge time. - **Messaging**: users on older devices stop receiving updates rather than being uninstalled, so their installed version keeps talking to your backend. ## Plugins and native SDKs The effective minimum of the final app is the **highest** `minSdk` declared anywhere in the dependency graph: the app itself, every Flutter plugin's Android module, and every native library those plugins pull in. That is why the failure shows up at manifest-merge time rather than when you add the dependency to `pubspec.yaml`. Before adopting a plugin for a core feature, check its Android `minSdk` against the devices the product must support — an older plugin version or an alternative package may keep the minimum where it is. | Change | Effect | |---|---| | Keep `flutter.minSdkVersion` | follows Flutter's supported minimum on upgrade | | Set a higher literal | excludes older devices; required by some plugins | | Set a literal below Flutter's minimum | unsupported; old values are migrated back |

  • What does the Flutter tool print when a plugin's minSdk is higher than the app's?
    It recognises the manifest-merger error and prints a box saying the plugin requires a higher Android SDK version, showing the `minSdkVersion` to add under `defaultConfig`, warning that users below that level lose access, and suggesting a plugin version supporting lower levels instead.
  • Why might a team pin minSdk to a literal equal to Flutter's current default?
    So that a Flutter upgrade cannot silently change which devices can install the app. The team then raises it deliberately, after checking device reach, instead of discovering the change from store statistics.

saying these in an interview costs you the question

  • Thinks flutter.minSdkVersion is a value the developer must define
  • Lowers minSdk below Flutter's minimum to reach older devices
  • Raises minSdk without checking how many active devices it drops
  • Confuses minSdk with targetSdk behaviour changes
  • Believes the value never changes across Flutter upgrades