ON THIS PAGE

No sections found

Related Posts

Flutter Build Modes Explained: Debug, Profile, and Release

Flutter Build Modes Explained: Debug, Profile, and Release

Feb 8, 2026

Mastering Flutter Clean Architecture: A Comprehensive Guide for 2026

Mastering Flutter Clean Architecture: A Comprehensive Guide for 2026

Feb 15, 2026

Top 50 Flutter Interview Questions & Answers for 2026: From Junior to Lead

Top 50 Flutter Interview Questions & Answers for 2026: From Junior to Lead

Feb 15, 2026

Quick Navigation

AboutProjectsEducationExperienceSkillsAwards

Connect

LinkedInXFacebookInstagramMediumRSS

Resources

BlogDownload CV

Dependencies

Quick Settings TileFlutter Ex KitDotted Line Flutter

Contact

Jaipur, Rajasthan, IndiaSupport
© 2026 Puneet Sharma•All rights reserved
Privacy Policy•Terms of Service•Disclaimer
Last updated: Jan 2026
Made withby Puneet

Flutter Flavors: How to Configure Dev, Staging, and Production Builds

Published onFebruary 12, 2026 (1mo ago)

Flutter Flavors Banner

Flutter Flavors: How to Configure Dev, Staging, and Production Builds

In modern app development, managing different environments is a core requirement. In Flutter, a flavor is the standard way to define multiple versions of your application from a single codebase. Each flavor can have its own configuration, environment variables, app name, package identifiers, icons, and API endpoints.

Using flavors is critical when you need:

  • Development (Dev): Connected to sandbox APIs with verbose logging.
  • Staging: For QA testing in an environment that mimics production.
  • Production (Prod): The stable version released to real users.

Think of flavors as "variants" or "schemes" that allow you to switch environments seamlessly without manual code changes.

Why Use Flavors Instead of hardcoding?

Hardcoding URLs and keys is error-prone and insecure. Flavors provide a clean separation of concerns, ensuring that development data never leaks into production. This is especially important when integrating with services like Firebase, where you often want separate projects for each environment.


🛠️ Step-by-Step Implementation Guide

Setting up flavors involves both Dart-side configuration and platform-specific (Android/iOS) setup.

1. Create Config Files

Create a folder like lib/config/ and inside it, add separate Dart files for each flavor:

lib/config/dev_config.dart

class Config {
  static const String appName = "MyApp Dev";
  static const String apiBaseUrl = "https://dev-api.example.com";
  static const bool enableLogging = true;
}

lib/config/staging_config.dart

class Config {
  static const String appName = "MyApp Staging";
  static const String apiBaseUrl = "https://staging-api.example.com";
  static const bool enableLogging = true;
}

lib/config/prod_config.dart

class Config {
  static const String appName = "MyApp";
  static const String apiBaseUrl = "https://api.example.com";
  static const bool enableLogging = false;
}

2. Create Entry Points for Each Flavor

You can have separate main.dart files for each flavor:

lib/main_dev.dart

import 'package:flutter/material.dart';
import 'config/dev_config.dart' as config;
import 'app.dart';
 
void main() {
  runApp(App(config: config.Config()));
}

lib/main_staging.dart

import 'package:flutter/material.dart';
import 'config/staging_config.dart' as config;
import 'app.dart';
 
void main() {
  runApp(App(config: config.Config()));
}

lib/main_prod.dart

import 'package:flutter/material.dart';
import 'config/prod_config.dart' as config;
import 'app.dart';
 
void main() {
  runApp(App(config: config.Config()));
}

3. Use Config in Your App

lib/app.dart

import 'package:flutter/material.dart';
 
class App extends StatelessWidget {
  final dynamic config;
 
  const App({super.key, required this.config});
 
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: config.appName,
      home: Scaffold(
        appBar: AppBar(title: Text(config.appName)),
        body: Center(
          child: Text('API Base URL: ${config.apiBaseUrl}'),
        ),
      ),
    );
  }
}

4. Running a Specific Flavor

Use the following commands to run or build your app with a specific flavor:

# Run Development
flutter run --flavor dev -t lib/main_dev.dart
 
# Run Staging
flutter run --flavor staging -t lib/main_staging.dart
 
# Run Production
flutter run --flavor prod -t lib/main_prod.dart

🤖 Setup in Android (build.gradle)

On Android, we use Product Flavors. Open android/app/build.gradle and add:

android {
    ...
    flavorDimensions "env"
    productFlavors {
        dev {
            dimension "env"
            applicationId "com.example.myapp.dev"
            resValue "string", "app_name", "MyApp Dev"
        }
        staging {
            dimension "env"
            applicationId "com.example.myapp.staging"
            resValue "string", "app_name", "MyApp Staging"
        }
        prod {
            dimension "env"
            applicationId "com.example.myapp"
            resValue "string", "app_name", "MyApp"
        }
    }
}

🍎 Setup in iOS (Xcode)

For iOS, you need to create Custom Schemes:

  1. Open your project in Xcode.
  2. Go to Product > Scheme > Manage Schemes.
  3. Duplicate the default scheme and name them dev, staging, and prod.
  4. Create corresponding Build Configurations in Project Settings.

💡 Best Practices for Flutter Flavors

  • Combine with Build Modes: Flavors define where the app runs (Dev vs Prod), while Build Modes define how it runs (Debug vs Release).
  • Use .env Files: For sensitive keys, consider using flutter_dotenv alongside flavors.
  • CI/CD Integration: Automate your builds using the --flavor flag in your pipelines.

Conclusion

Implementing flavors early in your project lifecycle saves significant time and prevents deployment errors. It allows you to maintain a professional development workflow that scales with your team.

For more advanced configuration details, check out the Official Flutter Documentation on Flavors.

Happy Coding! 🚀

Previous Post

Flutter Build Modes Explained: Debug, Profile, and Release

Next Post

Top 50 Flutter Interview Questions & Answers for 2026: From Junior to Lead