Flutter Flavors Setup For Android and IOS

0

After Flutter flavors setup for Android and iOS for the first time and conducting extensive research, I soon realized that there are few up-to-date and accessible beginner’s guides to Flutter flavors. So, I have decided to write a blog on Medium to share my experience and everything I have learned in a step-by-step process. I hope this guide can help make it a little simpler for others to set up Flutter flavors and avoid the confusion I went through. Let’s get started!

Why Do We Use Flavors in Flutter?

The goal of flavors in Flutter is to test new features and updates safely without affecting the already published app. We use the same codebase but run it in different environments for development and testing.

Each of these versions could come with:

  • Different API URLs
  • Different app names/icons
  • Different Firebase projects
  • Some features turned on or off

Instead of managing separate projects for each version, Flutter flavors allow us to manage everything within a single project. This keeps things clean, reduces errors, and speeds up development.

On the other hand, the video demo for Flutter Flavors Setup for Android and IOS

Step-by-Step Guide to Setting Up Flutter Flavors

I’ll cover both Android and iOS setups for flavors. First, we will start with the iOS setup.

First, decide what flavors you need. For this guide, let’s assume we’re creating three flavors:

  • dev: For development, the developer and tester can use.
  • admin: For the admin app.
  • user: For production, ready for your users.

Open the project in Xcode and start to set up the flavors environment for iOS. After you click the runner on the top menu, the result looks like in the image below, and select the Manage Schemes.

When you open Manage Schemes and go to AutoCreate Schemes, you’ll notice that only the default Runner scheme is listed at first. To add the flavors you need for your project, click the plus (+) icon in the bottom-left corner and create a new scheme for each flavor.

After you have added the required schemes, close them.

After you’ve successfully added the schemes, follow these steps to configure them:

  1. Go to the Runner project in Xcode.
  2. Select the Info tab.
  3. Under Configurations, you’ll see options for DebugRelease, and Profile.
  4. For each scheme (flavor) you created, add separate configurations for DebugRelease, and Profile.
  • You can do this by duplicating the existing configurations and renaming them (e.g., dev-Debugprod-Release, etc.).

5. Make sure each scheme is properly linked to its matching configuration.

This setup allows each flavor to run with its own environment and build settings, whether you’re debugging, profiling, or releasing the app.

Add Configurations Flutter Flavors

After creating your custom schemes and build configurations, the next step is to link the correct configuration (Debug, Release, or Profile) to each scheme.

Here’s how to do it:

  1. On Xcode and go to the top menu bar:
    Product > Scheme > Manage Schemes...
  2. Select your custom scheme (in your case, for example, user).
  3. Click Edit… (or double-click the scheme name) to open the scheme editor.
  4. In the left sidebar, you’ll see different actions like RunTestProfileAnalyze, and Archive.
  5. For each action:
  • Choose the correct Build Configuration from the dropdown.
    For example:
  • Run → Debug-user
  • Test → Debug-user
  • Profile → Profile-user
  • Archive → Release-user

Repeat this for all other schemes(user, admin, dev) and their corresponding configurations.

This step is important because it ensures that each flavor runs with the right settings, whether you’re testing in debug mode or preparing a release build.

It’s time to set the Product Name and Bundle Identifier for each flavor (admin, dev, user) now that your schemes and configurations are complete. This is what enables you to create distinct app builds with distinct identities, which can then be published independently or installed side by side on a device.

  1. Select the Runner Target in Xcode.
  2. Go to the Build Settings tab and select all and combined.

To fully separate your app flavors (like admin, dev, and user), you need to set a unique Bundle Identifier and Product Name for each flavor and each build configuration: DebugRelease, and Profile.

This is important, so each version:

  • Has its own identity (can be installed separately on devices),
  • Uses the correct Firebase setup (per target),
  • Can be submitted individually to TestFlight or the App Store if needed.

✅ 1. Set the Bundle Identifier

In the search bar, type:

bundle identifier
  • Click the filter icon next to the search bar and make sure All is selected This reveals all configurations, not just one.
Bundle Identifier
  • Under Packaging > Product Bundle Identifier, assign a unique identifier for each flavor + configuration:

Example:

Debug-admin     → com.example.flutterFlavors.admin
Debug-dev       → com.example.flutterFlavors.dev
Debug-user      → com.example.flutterFlavors

Release-admin   → com.example.flutterFlavors.admin
Release-dev     → com.example.flutterFlavors.dev
Release-user    → com.example.flutterFlavors

Profile-admin   → com.example.flutterFlavors.admin
Profile-dev     → com.example.flutterFlavors.dev
Profile-user    → com.example.flutterFlavors

✅ 2. Set the Product Name

In the same Build Settings tab, search for:

product name
  • Again, make sure all is selected in the filter.
  • Under Packaging > Product Name, set a clear name for each build. This is the name that appears under the app icon on a device.

Example(set any name that you want):

Debug-admin     → EcommerceAdmin
Debug-dev       → EcommerceDev
Debug-user      → Ecommerce

Release-admin   → EcommerceAdmin
Release-dev     → EcommerceDev
Release-user    → Ecommerce

Profile-admin   → EcommerceAdmin
Profile-dev     → EcommerceDev
Profile-user    → Ecommerce

Now the project is cleanly separated by flavors and configurations. Each one can behave differently, point to different environments, and even look slightly different if needed (icon/name).

To make sure your app’s display name (the name that appears below the app icon on a device) matches the name you’ve set in Product Name for each flavor, you need to update the Bundle Display Name.

Bundle Display Name
  1. In Xcode, open the Info.plist(or info) file inside the Runner folder.
  2. Find the key called Bundle display name.
  • If it’s not already there, add a new entry:(if not, most of the time it will be there)
  • Key: Bundle display name
  • Type: String
  • Value: $(PRODUCT_NAME)

3. If It Bundle display name is already there by double-clicking on it, the value is set to the $(PRODUCT_NAME)

  1. Save the file.
    By setting it to $(PRODUCT_NAME)You’re telling Xcode to automatically use whatever you defined in the Product Name field in your Build Settings, which keeps things consistent across flavors. In the top left corner, there is a play button. Try to run on each flavor.

IOS flavors setup is completed

Android Setup for Flutter Flavors

As compared to IOS setup, the Android setup is quite easy,

  1. Open android/app/build.gradle.kts
  2. After buildTypes inside the android{}
  3. Add flavorDimensions and productFlavors
    flavorDimensions += "default"

    productFlavors {
        create("user") {
            resValue("string", "app_name", "Ecommerce")
        }
        create("admin") {
            resValue("string", "app_name", "Ecommerce.admin")
            applicationIdSuffix = ".admin"
        }
        create("dev") {
            resValue("string", "app_name", "Ecommerce.dev")
            applicationIdSuffix = ".dev"
        }
    }
  • resValue “string”, “app_name”, “…”
    This sets the app name that appears on the launcher for each flavor.
    You’ll use this later in AndroidManifest.xml.
  • applicationIdSuffix ".admin"
    Adds a suffix to the app’s package name (e.g. com.yourcompany.ecommerce.admin)
    This ensures each version of the app can be installed separately.
  • flavorDimensions += "default"
    Required for Android to understand that these flavors are grouped under one dimension.

Each flavor will now have a different app_name. To apply it:

In android/app/src/main/AndroidManifest.xmlReplace the hardcoded app name with:

android:label="@string/app_name"

Android will now use the correct name fromresValue. Android setup is also completed 👍 .

Run and Test All Flavor Environment

To run the project, create a one-file and give it the name I will give global.dart

Next, create a Dart file according to how many flavors you have created (currently, I have created 3, which are admin, dev, and user), and I have created 3 Dart files with a main function, which are

main_admin.dart

main_dev.dart

main_dev.dart

main_user.dart

In all the Dart files (main_admin.dartmain_user.dart, and main_dev.dartWe are calling the MyApp, which displays the base URL on the screen based on the selected flavor.

To make running different flavors easier in VS Code, you can create a launch.json file. This allows you to quickly launch a specific flavor (like admindev, or user) directly from the Run menu — no need to type commands in the terminal every time.

  1. In VS Code, go to the Run and Debug tab (on the left sidebar).
  2. Click on “create a launch.json file” (or gear icon ⚙️).
  1. Select Dart as the environment.
  2. Replace the contents with this:
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "admin",
      "request": "launch",
      "type": "dart",
      "program": "lib/main_admin.dart",
      "args": ["--flavor", "admin", "target", "lib/main_admin.dart"]
    },
    {
      "name": "user",
      "request": "launch",
      "type": "dart",
      "program": "lib/main_user.dart",
      "args": ["--flavor", "user", "target", "lib/main_user.dart"]
    },
    {
      "name": "dev",
      "request": "launch",
      "type": "dart",
      "program": "lib/main_dev.dart",
      "args": ["--flavor", "dev", "target", "lib/main_dev.dart"]
    }
  ]
}

What this does:

  • "name" — The label is shown in the VS Code Run menu.
  • "program" — Points to the Dart entry file for that flavor.
  • "args" — Tells Flutter which flavor to run (--flavor) and which Dart file to target.

(You need to change the name, program, and args according to your project)

Finally, select the flavors and run the app.

Wrapping Up

Overall, Flutter Flavors Setup for Android and IOS may seem tricky at first, but once it’s done, it makes managing multiple environments so much easier. I hope this step-by-step guide helped you avoid the confusion I faced in the beginning.

Additionally, you can also watch the YouTube tutorial, which makes it easy for you to set up the flavors. Also, I have set up a Firebase for both flavors.

Also, learn Stripe payment integration in Flutter.

If you found this helpful, feel free to share it with others — and happy coding! 🙌

Previous articleStripe Payment Integration in Flutter
Next articleStore API Key in Firebase Function

LEAVE A REPLY

Please enter your comment!
Please enter your name here