Debug Tools
How to override feature flags in the Flutter debug panel
Enterprise Reference for app_debugger_feature_flag: every variable, option and package it generates. Command: archipelago generate app_debugger_feature_flag
Generate the feature flag spoofer for app_debugger, see how the override delegate takes priority, set overrides in the panel and in code, and suspend one.
What you'll learn
- Generating the feature flag spoofer sub-brick for
app_debugger - Understanding how the spoofer delegate takes priority
- Overriding flags in the panel and in code
- Suspending an override without deleting it
Prerequisites
app_debuggeralready installed (see App Debugger Setup)feature_flag_sdkalready generated (see Feature Flag SDK)
Step 1: Generate the Brick
archipelago generate app_debugger_feature_flagThe CLI reads the two variables, uiKitPackageName and prefix, from archipelago.yaml. The spoofer works with any feature flag provider at runtime.
Step 2: Understand the Generated Packages
features/app_debugger_feature_flag/
├── app_debugger_feature_flag_api/ # FeatureFlagSpooferSDK, FlagOverride and SpooferUiKit
├── app_debugger_feature_flag/ # Debug implementation and Feature Flags tab
│ └── lib/src/
│ ├── feature_flag_spoofer_sdk_impl.dart
│ ├── feature_flag_spoofer_delegate.dart
│ └── feature_flag_spoofer_page.dart
└── app_debugger_feature_flag_noop/ # Production-flavor stubFlagOverride holds a flagKey, a value and an enabled flag. Set enabled to false to suspend an override without removing it.
Step 3: Check build_prepare
The brick adds the swap entry to build_prepare.yaml for you:
build_prepare:
mappings:
- debug: app_debugger_feature_flag
release: app_debugger_feature_flag_noopThe generated Fastfile runs dart run monorepo_toolkit build-prepare --flavor <flavor> before every build. Internal flavors keep the spoofer, also in release mode. The production flavor gets the noop.
Step 4: Check the Wiring
The hook wires the delegate for you. In features/app_debugger/app_debugger/lib/src/di/debug_tools.dart you find two blocks:
// archipelago:debug_panel_pages:start
GetIt.I<FeatureFlagSpooferSDK>();
// archipelago:debug_panel_pages:end
// archipelago:feature_flag_spoofer_delegate:start
final spooferDelegate = GetIt.I<FeatureFlagSpooferSDK>().delegate;
if (spooferDelegate != null) {
FeatureFlagDelegateRegistry.instance.register(spooferDelegate);
}
// archipelago:feature_flag_spoofer_delegate:endFeatureFlagManager reads the registry on every evaluation. The spoofer runs before the real providers. The noop returns a null delegate, so nothing registers in production.
Step 5: Verify in an Internal Flavor
Open the debug panel and select the Feature Flags tool. It lists every flag your providers know, grouped by source. Flip the switch on a bool flag to override it; flip it back to the provider value to remove the override. Tap any other flag to edit it on a full-screen page (JSON gets a validating editor with a Format button). The spoofer switch at the top turns every override off without deleting it. Overrides survive a restart.
To draw the tool with your own design system, register a SpooferUiKit; see Match your design system.
To set an override from code, for example in an integration test:
getIt<FeatureFlagSpooferSDK>().setOverride(
FlagOverride(
flagKey: 'new_checkout_flow',
value: FeatureFlagResult.enabled(),
),
);Step 6: Suspend, Remove or Clear
final spoofer = getIt<FeatureFlagSpooferSDK>();
// Suspend: keep the entry, use the real provider value
spoofer.setOverride(
FlagOverride(
flagKey: 'new_checkout_flow',
value: FeatureFlagResult.enabled(),
enabled: false,
),
);
spoofer.removeOverride('new_checkout_flow');
spoofer.clearAllOverrides();
// Keep every override but stop applying them
spoofer.setSpoofing(enabled: false);Overrides and the spoofer switch are saved to the app support directory and restored on the next launch. clearAllOverrides() removes the saved copy too.
Delegate Priority
| Position | Provider | Notes |
|---|---|---|
| First | Spoofer delegate | Panel overrides, highest priority |
| After | Your real providers | Remote config, local defaults |
Next Steps
- Set up App Debugger if you have not already
- Configure the Feature Flag SDK to manage your providers