Implement feature flag systems — progressive rollouts, A/B testing, kill switches, and experimentation frameworks with Firebase Remote Config or LaunchDarkly
Before starting, gather project context silently:
PORTFOLIO.md if it exists in the project root or parent directories for product/team contextcat package.json 2>/dev/null || cat build.gradle.kts 2>/dev/null || cat Podfile 2>/dev/null to detect stackgit log --oneline -5 2>/dev/null for recent changesls src/ app/ lib/ functions/ 2>/dev/null to understand project structureDesigns and implements feature flag systems for progressive rollouts, A/B experimentation, operational kill switches, and permission-based access control. Covers Firebase Remote Config, LaunchDarkly, and custom implementations across Android, iOS, and web. Every flag has a lifecycle, an owner, and a cleanup date.
Hard rules:
| Flag Type | Purpose | Lifespan | Example |
|---|---|---|---|
| Release Toggle | Gate incomplete features during development | Days–weeks (remove after launch) | show_new_checkout_flow |
| Experiment / A/B | Test hypotheses with controlled rollout | 2–6 weeks (remove after analysis) | experiment_pricing_page_v2 |
| Ops Toggle / Kill Switch | Disable features during incidents without deploy | Permanent (always present) | kill_switch_video_upload |
| Permission Toggle | Enable features for specific user segments | Long-lived (tied to entitlements) | enable_premium_analytics |
Before implementing, confirm:
Pattern: {type}_{feature}_{variant}
Types:
release_ — release toggle (temporary)
exp_ — experiment / A/B test (temporary)
ops_ — operational toggle / kill switch (permanent)
perm_ — permission toggle (long-lived)
Examples:
release_new_onboarding_flow
exp_checkout_single_page
ops_kill_switch_image_processing
perm_premium_export_csv
Rules:
- snake_case always
- Maximum 50 characters
- No version numbers in flag names (use variants instead)
- Prefix makes flag type instantly recognizable in dashboards
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ PROPOSED │────▶│ CREATED │────▶│ ACTIVE │────▶│ COMPLETE │────▶│ ARCHIVED │
└──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘
│ │ │
│ │ ▼
│ │ ┌──────────┐
│ └─────────▶│ CLEANUP │
│ └──────────┘
▼
┌──────────┐
│ REJECTED │
└──────────┘
State definitions:
PROPOSED: PR/ticket created requesting the flag
CREATED: Flag exists in provider with default value (off)
ACTIVE: Flag is being used for rollout or experiment
COMPLETE: Rollout is 100% or experiment concluded — flag value is decided
CLEANUP: Code removal PR created — removing flag checks from codebase
ARCHIVED: Flag deleted from provider, code cleaned up
REJECTED: Flag proposal denied (not needed, wrong approach)
Maintain a flag registry (Notion, Google Sheet, or YAML in repo):