growthbook_sdk_flutter 4.0.0  growthbook_sdk_flutter: ^4.0.0 copied to clipboard
growthbook_sdk_flutter: ^4.0.0 copied to clipboard
An open-source feature flagging and experimentation platform that makes it simple to alter features and execute A/B testing.
GrowthBook Flutter SDK #

๐ฏ Feature flags โข ๐งช A/B testing โข ๐ Analytics integration
Quick Start โข Features โข Documentation โข Examples โข Resources
Overview #
GrowthBook is an open source feature flagging and experimentation platform. This Flutter SDK allows you to use GrowthBook with your Flutter based mobile application.
Platform Support:
- ๐ฑ Android 21+ โข iOS 12+
- ๐บ tvOS 13+ โข โ watchOS 7+
- ๐ฅ๏ธ macOS โข Windows โข Linux
- ๐ Web (Flutter Web)
โจ Features #
- Lightweight - Minimal performance impact
- Type Safe - Full Dart/Flutter type safety
- Caching - Smart caching with TTL and stale-while-revalidate
- Cross-platform - Works on Android, iOS, Web, Desktop
๐๏ธ Core Capabilities #
- Feature Flags - Toggle features on/off without code deployments
- A/B Testing - Run experiments with statistical significance
- Targeting - Advanced user segmentation, variation weights and targeting rules
- Tracking - Use your existing event tracking (GA, Segment, Mixpanel, custom)
- Real-time Updates - Features update instantly via streaming
๐ฏ Advanced Features #
- Sticky Bucketing - Consistent user experiences across sessions
- Remote Evaluation - Server-side evaluation for enhanced security
- Multi-variate Testing - Test multiple variations simultaneously
- Rollout Management - Gradual feature rollouts with traffic control
๐ Supported Features #
| Feature | Support | Since Version | 
|---|---|---|
| โ Feature Flags | Full Support | All versions | 
| โ A/B Testing | Full Support | All versions | 
| โ Sticky Bucketing | Full Support | โฅ v3.8.0 | 
| โ Remote Evaluation | Full Support | โฅ v3.7.0 | 
| โ Streaming Updates | Full Support | โฅ v3.4.0 | 
| โ Prerequisites | Full Support | โฅ v3.2.0 | 
| โ Encrypted Features | Full Support | โฅ v3.1.0 | 
| โ v2 Hashing | Full Support | โฅ v3.1.0 | 
| โ SemVer Targeting | Full Support | โฅ v3.1.0 | 
| โ TTL Caching | Full Support | โฅ v3.9.10 | 
๐ Quick Start #
1. Installation #
Add to your pubspec.yaml:
dependencies:
  growthbook_sdk_flutter: ^3.9.10
2. Basic Setup #
import 'package:growthbook_sdk_flutter/growthbook_sdk_flutter.dart';
// Initialize the SDK
final sdk = await GBSDKBuilderApp(
  apiKey: "sdk_your_api_key",
  hostURL: "https://growthbook.io",
  attributes: {
    'id': 'user_123',
    'email': 'user@example.com',
    'country': 'US',
  },
  growthBookTrackingCallBack: (experiment, result) {
    // Track experiment exposures
    print('Experiment: ${experiment.key}, Variation: ${result.variationID}');
  },
).initialize();
// Use feature flags
final welcomeMessage = sdk.feature('welcome_message');
if (welcomeMessage.on) {
  print('Feature is enabled: ${welcomeMessage.value}');
}
// Run A/B tests
final buttonExperiment = GBExperiment(key: 'button_color_test');
final result = sdk.run(buttonExperiment);
final buttonColor = result.value ?? 'blue'; // Default color
3. Widget Integration #
class MyHomePage extends StatelessWidget {
  final GrowthBookSDK sdk;
  
  @override
  Widget build(BuildContext context) {
    final newDesign = sdk.feature('new_homepage_design');
    
    return Scaffold(
      body: newDesign.on 
        ? NewHomepageWidget() 
        : ClassicHomepageWidget(),
    );
  }
}
Analytics #
final sdk = await GBSDKBuilderApp(
  apiKey: "your_api_key",
  growthBookTrackingCallBack: (experiment, result) {
    // Google Analytics
    FirebaseAnalytics.instance.logEvent(
      name: 'experiment_viewed',
      parameters: {
        'experiment_id': experiment.key,
        'variation_id': result.variationID,
        'variation_name': result.key,
      },
    );
    
    // Mixpanel
    Mixpanel.track('Experiment Viewed', {
      'Experiment ID': experiment.key,
      'Variation ID': result.variationID,
    });
    
    // Custom analytics
    YourAnalytics.trackExperiment(experiment, result);
  },
).initialize();
๐ Documentation #
Configuration Options #
final sdk = await GBSDKBuilderApp(
  // Required
  apiKey: "sdk_your_api_key",
  hostURL: "https://growthbook.io",
  
  // User Context
  attributes: {
    'id': 'user_123',
    'email': 'user@example.com',
    'plan': 'premium',
    'country': 'US',
  },
  
  // Performance & Caching
  ttlSeconds: 300,              // Cache TTL (default: 60s)
  backgroundSync: true,         // Real-time updates
  
  // Testing & QA
  qaMode: false,                // Disable randomization for QA
  forcedVariations: {           // Force specific variations
    'button_test': 1,
  },
  
  // Analytics Integration
  growthBookTrackingCallBack: (experiment, result) {
    // Send to your analytics platform
    analytics.track('Experiment Viewed', {
      'experiment_id': experiment.key,
      'variation_id': result.variationID,
      'variation_name': result.key,
    });
  },
  
  // Advanced Features
  remoteEval: false,            // Server-side evaluation
  encryptionKey: "...",         // For encrypted features
).initialize();
Feature Flag Usage #
// Boolean flags
final isEnabled = sdk.feature('new_feature').on;
// String values
final welcomeText = sdk.feature('welcome_message').value ?? 'Welcome!';
// Number values  
final maxItems = sdk.feature('max_items').value ?? 10;
// JSON objects
final config = sdk.feature('app_config').value ?? {
  'theme': 'light',
  'animations': true,
};
// Check feature source
final feature = sdk.feature('premium_feature');
switch (feature.source) {
  case GBFeatureSource.experiment:
    print('Value from A/B test');
    break;
  case GBFeatureSource.force:
    print('Forced value');
    break;
  case GBFeatureSource.defaultValue:
    print('Default value');
    break;
}
Experiments - A/B Testing #
// Define experiment
final experiment = GBExperiment(
  key: 'checkout_button_test',
  variations: ['๐ Buy Now', '๐ณ Purchase', 'โจ Get It Now'],
  weights: [0.33, 0.33, 0.34], // Traffic distribution
);
// Run experiment
final result = sdk.run(experiment);
// Use result
Widget buildButton() {
  final buttonText = result.value ?? '๐ Buy Now';
  return ElevatedButton(
    onPressed: () => handlePurchase(),
    child: Text(buttonText),
  );
}
// Track conversion
if (purchaseCompleted) {
  // Your analytics will receive this via trackingCallBack
}
User Attributes & Targeting #
// Update user attributes dynamically
sdk.setAttributes({
  'plan': 'enterprise',
  'feature_flags_enabled': true,
  'last_login': DateTime.now().toIso8601String(),
});
// Target users with conditions
// Example: Show feature only to premium users in US
// This is configured in GrowthBook dashboard, not in code
๐ง Advanced Features #
Smart Caching Strategy #
The SDK implements an intelligent caching system for optimal performance:
final sdk = await GBSDKBuilderApp(
  apiKey: "your_api_key",
  ttlSeconds: 300, // Cache TTL: 5 minutes
  backgroundSync: true, // Enable background refresh
).initialize();
How it works:
- ๐ Instant Response - Serve cached features immediately
- ๐ Background Refresh - Fetch updates in the background
- โก Stale-While-Revalidate - Show cached data while updating
- ๐ Smart Invalidation - Refresh only when needed
Benefits:
- โ Zero loading delays for feature flags
- โ Always up-to-date with background sync
- โ Reduced API calls with intelligent caching
- โ Offline resilience with cached fallbacks
Sticky Bucketing #
Ensure consistent user experiences across sessions:
class MyAppStickyBucketService extends GBStickyBucketService {
  @override
  Future<Map<String, String>?> getAllAssignments(
    Map<String, dynamic> attributes,
  ) async {
    // Retrieve from local storage
    final prefs = await SharedPreferences.getInstance();
    final json = prefs.getString('gb_sticky_assignments');
    return json != null ? jsonDecode(json) : null;
  }
  
  @override
  Future<void> saveAssignments(
    Map<String, dynamic> attributes,
    Map<String, String> assignments,
  ) async {
    // Save to local storage
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString('gb_sticky_assignments', jsonEncode(assignments));
  }
}
// Use with SDK
final sdk = await GBSDKBuilderApp(
  apiKey: "your_api_key",
  stickyBucketService: MyAppStickyBucketService(),
).initialize();
Remote Evaluation #
For enhanced security and server-side evaluation:
final sdk = await GBSDKBuilderApp(
  apiKey: "your_api_key",
  remoteEval: true, // Enable remote evaluation
  attributes: userAttributes,
).initialize();
// Features are evaluated server-side
// Sensitive targeting rules never reach the client
Real-time Updates #
final sdk = await GBSDKBuilderApp(
  apiKey: "your_api_key",
  backgroundSync: true, // Enable streaming updates
).initialize();
// Features automatically update when changed in GrowthBook
// No need to restart the app or refresh manually
๐ก Examples #
E-commerce App #
class ProductPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final sdk = context.read<GrowthBookSDK>();
    
    // Feature flags
    final showReviews = sdk.feature('show_product_reviews').on;
    final freeShipping = sdk.feature('free_shipping_threshold').value ?? 50.0;
    
    // A/B test for pricing display
    final pricingExperiment = GBExperiment(key: 'pricing_display_test');
    final pricingResult = sdk.run(pricingExperiment);
    
    return Scaffold(
      body: Column(
        children: [
          ProductImage(),
          ProductTitle(),
          
          // Dynamic pricing display based on A/B test
          if (pricingResult.value == 'with_discount')
            PricingWithDiscount()
          else
            StandardPricing(),
            
          // Conditional features
          if (showReviews) ProductReviews(),
          if (freeShipping > 0) FreeShippingBanner(threshold: freeShipping),
          
          AddToCartButton(),
        ],
      ),
    );
  }
}
Gradual Feature Rollout #
class NewFeatureService {
  final GrowthBookSDK sdk;
  
  NewFeatureService(this.sdk);
  
  bool get isNewDashboardEnabled {
    final feature = sdk.feature('new_dashboard_v2');
    
    // Feature is rolled out gradually:
    // 0% โ 5% โ 25% โ 50% โ 100%
    // Configured in GrowthBook dashboard
    return feature.on;
  }
  
  Widget buildDashboard() {
    return isNewDashboardEnabled 
      ? NewDashboardWidget()
      : LegacyDashboardWidget();
  }
}
๐ ๏ธ Development #
Local Development Setup #
1. Clone and Setup
# Clone the repository
git clone https://github.com/growthbook/growthbook-flutter.git
cd growthbook-flutter
# Install dependencies
flutter pub get
# Generate code (for json_serializable)
dart run build_runner build --delete-conflicting-outputs
2. Run Tests
# Run all tests
flutter test
# Run tests with coverage
flutter test --coverage
# Run specific test file
flutter test test/features/feature_test.dart
3. Code Generation
The SDK uses json_serializable for JSON parsing. When you modify model classes with @JsonSerializable(), run:
# Watch for changes and auto-generate
dart run build_runner watch
# One-time generation
dart run build_runner build --delete-conflicting-outputs
4. Linting and Formatting
# Check linting
dart analyze
# Format code
dart format .
# Fix auto-fixable issues
dart fix --apply
5. Building Examples
cd example
flutter pub get
flutter run
Testing #
// Mock SDK for testing
class MockGrowthBookSDK implements GrowthBookSDK {
  final Map<String, dynamic> mockFeatures;
  
  MockGrowthBookSDK({required this.mockFeatures});
  
  @override
  GBFeatureResult feature(String key) {
    final value = mockFeatures[key];
    return GBFeatureResult(
      value: value,
      on: value == true,
      source: GBFeatureSource.force,
    );
  }
}
// Use in tests
void main() {
  testWidgets('shows new feature when enabled', (tester) async {
    final mockSDK = MockGrowthBookSDK(
      mockFeatures: {'new_feature': true},
    );
    
    await tester.pumpWidget(MyApp(sdk: mockSDK));
    
    expect(find.text('New Feature'), findsOneWidget);
  });
}
Build Integration #
// Different configurations for different environments
final sdk = await GBSDKBuilderApp(
  apiKey: kDebugMode 
    ? "sdk_dev_your_dev_key"
    : "sdk_prod_your_prod_key",
  hostURL: kDebugMode 
    ? "https://growthbook-dev.yourcompany.com"
    : "https://growthbook.yourcompany.com",
  qaMode: kDebugMode, // Disable randomization in debug
).initialize();
Contributing #
We welcome contributions! Here's how to get started:
- Fork the repository and create a feature branch
- Make your changes following our coding conventions
- Add tests for any new functionality
- Ensure all tests pass: flutter test
- Format code: dart format .
- Submit a pull request with a clear description
Pull Request Guidelines:
- โ Include tests for new features
- โ Update documentation if needed
- โ Follow existing code style
- โ Keep commits atomic and well-described
- โ Reference any related issues
Release Process:
- Uses automated releases via release-please
- Follow conventional commits: feat:,fix:,docs:, etc.
- Automatic version bumping and changelog generation
๐ Resources #
- ๐ Official Documentation
- ๐ฏ GrowthBook Dashboard
- ๐ฌ Community Slack
- ๐ Report Issues
- ๐ฆ pub.dev Package
๐ License #
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Acknowledgments #
Originally contributed by the team at Alippo. The core GrowthBook platform remains open-source and free forever.
Made with โค๏ธ by the GrowthBook community