Skip to main content

Set up Flutter flavors for Windows

How to create Flutter flavors for Windows desktop apps.

This guide shows you how to create Flutter flavors for Windows desktop apps.

Overview

#

A Flutter flavor represents a collection of settings that define how a specific version of your app builds and runs. For example, a flavor can determine the window title, application icon, API endpoint, asset set, and logging configuration for a build.

On Windows, Flutter uses CMake to configure and build the native desktop runner. When you run flutter run or flutter build with the --flavor flag, Flutter writes the flavor name into windows/flutter/ephemeral/generated_config.cmake as the FLUTTER_APP_FLAVOR variable, and isolates the build outputs in a flavor-specific directory.

The following table illustrates the build directories that Flutter creates when a project defines two flavors (staging, production) and two build modes (debug, release):

FlavorBuild modeOutput directory
stagingdebugbuild/windows/<arch>/staging/runner/Debug/
production debug build/windows/<arch>/production/runner/Debug/
staging release build/windows/<arch>/staging/runner/Release/
production release build/windows/<arch>/production/runner/Release/

Create and run flavors

#

Passing --flavor works on Windows without any CMake configuration. Existing Flutter projects support flavors with no template updates or configuration changes required. When you pass --flavor, Flutter isolates the build directory, populates appFlavor, and filters flavor-specific assets automatically.

To try flavors with a sample project, complete the following steps:

  1. Create a new Flutter project called flavors_example:

    flutter create flavors_example
    cd flavors_example
    
  2. Verify that your flavors run correctly:

    Run the staging flavor:

    flutter run -d windows --flavor staging
    

    Run the production flavor:

    flutter run -d windows --flavor production
    

To customize native runner settings for each flavor—such as the window title or application icon—refer to Customize configurations.

Launch a flavor

#

After you define flavors for your app, run, build, or test a specific flavor using the --flavor flag with the Flutter CLI.

Run a flavor in debug mode

#

To run a specific flavor during development, pass the --flavor option to flutter run:

flutter run -d windows --flavor <flavor_name>

Replace <flavor_name> with the name of your flavor (for example, staging or production).

Build a release binary

#

To build a release executable for a specific flavor, pass the --flavor option to flutter build:

flutter build windows --flavor <flavor_name>

Flutter outputs the compiled executable to build/windows/<arch>/<flavor_name>/runner/Release/.

Run tests with a flavor

#

The --flavor option also works with flutter test and flutter drive, allowing you to run unit, widget, or integration tests against a specific flavor configuration:

flutter test --flavor <flavor_name>

Use flavors in Flutter code

#

After adding flavors, you can adjust app behavior—such as selecting API endpoints, toggling features, or setting analytics keys—based on the active flavor.

The Flutter framework provides the appFlavor constant in the services library, which identifies the flavor used to run or build your app.

  1. Import the services library:

    Add the following import to your Dart file:

    dart
    import 'package:flutter/services.dart';
    
  2. Read the flavor value:

    Use the appFlavor constant in your application logic (often in main()) to handle flavor-specific configuration:

    dart
    void main() {
      if (appFlavor == 'production') {
        Config.apiUrl = 'https://api.example.com';
      } else if (appFlavor == 'staging') {
        Config.apiUrl = 'https://staging.api.example.com';
      }
    
      runApp(const MyApp());
    }
    

Customize configurations

#

To differentiate the native Windows runner per flavor—such as giving each flavor a unique window title or application icon—configure CMake to generate the runner source and resource files using configure_file.

Configure CMake for native settings

#

CMake evaluates windows/runner/CMakeLists.txt after FLUTTER_APP_FLAVOR is defined. You can inspect this variable to configure flavor-specific values, then use configure_file to substitute them into template files for the C++ runner (main.cpp) and the Windows resource script (Runner.rc).

In windows/runner/CMakeLists.txt, add the following block before the add_executable(${BINARY_NAME} ...) line:

windows/runner/CMakeLists.txt
cmake
# Configure flavor-specific settings.
if(DEFINED FLUTTER_APP_FLAVOR)
  if(FLUTTER_APP_FLAVOR STREQUAL "staging")
    set(RUNNER_APP_ICON "staging.ico")
    set(WINDOW_TITLE "Staging App")
  elseif(FLUTTER_APP_FLAVOR STREQUAL "production")
    set(RUNNER_APP_ICON "production.ico")
    set(WINDOW_TITLE "Production App")
  endif()
else()
  set(RUNNER_APP_ICON "app_icon.ico")
  set(WINDOW_TITLE "${BINARY_NAME}")
endif()

configure_file(
  "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp.in"
  "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp"
  @ONLY
)

configure_file(
  "${CMAKE_CURRENT_SOURCE_DIR}/Runner.rc.in"
  "${CMAKE_CURRENT_SOURCE_DIR}/Runner.rc"
  @ONLY
)

Create distinct window titles

#

To display a flavor-specific window title when the app launches:

  1. Rename windows/runner/main.cpp to windows/runner/main.cpp.in.

  2. In windows/runner/main.cpp.in, find where window.Create is called and replace the hardcoded title with @WINDOW_TITLE@:

    windows/runner/main.cpp.in
    cpp
      if (!window.Create(L"@WINDOW_TITLE@", origin, size)) {
        return EXIT_FAILURE;
      }
    

    When CMake configures the build, it replaces @WINDOW_TITLE@ with the window title for the selected flavor.

Create distinct app icons

#

To provide unique desktop icons for each flavor:

  1. Prepare your icon files in .ico format (for example, staging.ico and production.ico) and place them in windows/runner/resources/ alongside the default app_icon.ico.

  2. Rename windows/runner/Runner.rc to windows/runner/Runner.rc.in.

  3. In windows/runner/Runner.rc.in, locate the IDI_APP_ICON line and update the icon path to use @RUNNER_APP_ICON@:

    windows/runner/Runner.rc.in
    rc
    IDI_APP_ICON            ICON                    "resources\\@RUNNER_APP_ICON@"
    

    You can also update the metadata strings, such as FileDescription and ProductName, to use @WINDOW_TITLE@:

    windows/runner/Runner.rc.in
    rc
    VALUE "FileDescription", "@WINDOW_TITLE@" "\0"
    VALUE "ProductName",     "@WINDOW_TITLE@" "\0"
    

Bundle assets by flavor

#

If you have assets that only apply to a specific flavor, configure Flutter to only bundle those assets when building that flavor. This prevents unused assets from increasing your application bundle size.

To bundle assets conditionally, add the flavors list to an asset entry in pubspec.yaml:

pubspec.yaml
yaml
flutter:
  assets:
    - assets/common/
    - path: assets/staging/
      flavors:
        - staging
    - path: assets/production/
      flavors:
        - production

To learn more, consult the assets field in Flutter pubspec options.

Set a default flavor

#

To specify a flavor to use when running or building without the --flavor flag, add the default-flavor property to pubspec.yaml:

pubspec.yaml
yaml
flutter:
  default-flavor: staging

To learn more, consult the default-flavor field in Flutter pubspec options.

More information

#

For more information on flavors and desktop deployment, consult the following resources: