Flutter
mobile development
app versioning
build number
software development

How to set build and version number of Flutter app

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Flutter versioning looks simple on the surface, but it still has to map into Android and iOS release rules correctly. The key is knowing which number is user-facing, which number is for store ordering, and where Flutter expects you to define them.

Use the version Field in pubspec.yaml

In a standard Flutter project, the main version definition lives in pubspec.yaml.

yaml
version: 1.4.2+27

This format has two parts:

  1. 1.4.2 is the user-facing version name.
  2. 27 is the build number.

The left side is what users typically see in the app store or settings screen. The right side is the monotonically increasing internal build identifier that the stores use to distinguish uploads of the same release line.

For example, if you fix a packaging issue without changing the public release version, you might keep the version name and only bump the build:

yaml
version: 1.4.2+28

That means "same app release series, newer distributable build."

Understand How Flutter Maps to Android and iOS

Flutter translates the values into native platform settings during the build.

On Android:

  1. The version name maps to the visible version string.
  2. The build number maps to the integer code used by the platform for upgrade ordering.

On iOS:

  1. The version name maps to the short bundle version string.
  2. The build number maps to the bundle build field.

You usually do not edit those generated values manually in native files unless the project has custom native build logic. For most Flutter apps, pubspec.yaml is the single source of truth.

Override Values from the Command Line

You can also set the version name and build number at build time. This is useful when CI or release automation should stamp the artifact with pipeline-specific metadata instead of relying only on the checked-in pubspec.yaml value.

bash
flutter build apk --build-name=1.5.0 --build-number=42

The same pattern works for other targets:

bash
flutter build ios --build-name=1.5.0 --build-number=42

This approach is practical when the repository keeps a stable baseline version in pubspec.yaml, but the delivery pipeline needs to assign a unique build for each upload candidate.

Pick a Versioning Policy Before Releases Start

Most teams avoid confusion by choosing one policy early:

  1. Semantic versioning for public releases such as 2.3.1.
  2. A strictly increasing build number for every distributable build.

That policy matters more than the exact numbering style. What breaks release pipelines is inconsistency, such as reusing build numbers or bumping one platform differently from the other.

A simple release progression might look like this:

text
11.0.0+1
21.0.0+2
31.1.0+3
41.1.1+4

Users see 1.0.0, 1.1.0, and 1.1.1, while the stores see a clean sequence of build identifiers.

Verify the Result in Native Projects

If the app uses custom Gradle, Xcode, flavors, or multiple targets, it is worth verifying the generated values rather than assuming they propagated correctly.

Common checks:

  1. Build the app.
  2. Open the Android or iOS output metadata.
  3. Confirm the visible version and build number match the intended release.

For Android projects with custom flavors, make sure version overrides do not conflict with per-flavor configuration. For iOS, ensure any manually edited native settings are not silently drifting away from the Flutter version field.

Use CI to Prevent Versioning Mistakes

Manual versioning works for small projects, but once releases become frequent, automation reduces errors. A simple CI step can reject builds where the build number did not increase or can derive it from the pipeline run number.

For example, a release job might do this:

bash
flutter build appbundle \
  --build-name=2.0.0 \
  --build-number=$CI_PIPELINE_NUMBER

The exact environment variable depends on your CI system, but the principle is stable: keep the public version intentional and the build number unique.

Common Pitfalls

  • Changing the visible version and forgetting that store uploads still require a higher internal build number.
  • Editing native Android or iOS version values manually while also relying on pubspec.yaml, which creates drift.
  • Reusing a build number in CI and then being blocked by app store validation rules.
  • Treating the build number as user-facing release information instead of an internal release counter.
  • Starting versioning without a stable policy and then trying to clean up inconsistency after releases already exist.

Summary

  • Set the main Flutter app version in pubspec.yaml as version_name+build_number.
  • The version name is user-facing, while the build number must keep increasing for release ordering.
  • Flutter maps that combined value into Android and iOS native fields automatically in normal projects.
  • Command-line overrides are useful for CI and release automation.
  • Consistent versioning policy matters more than complicated numbering schemes.

Course illustration
Course illustration

All Rights Reserved.