Feature flags
Plan for feature flag architecture from the start. All features MUST be gated behind flags from initial implementation.
Architecture decisions
- Interface first — define a
FeatureFlagProviderinterface (isEnabled(key) -> Bool) early. This is a dependency injection boundary — the provider can be swapped without touching feature code. - Local default — start with a local storage backend (UserDefaults, SharedPreferences, localStorage, JSON config). Plan for a remote backend (LaunchDarkly, Firebase Remote Config, Azure App Configuration) as a later swap via DI.
- Flag inventory — each feature spec SHOULD list its flag keys in a Feature Flags section. Plan the flag naming convention upfront (e.g.,
feature.auth.biometric,feature.editor.markdown).
What to gate
- All new user-visible features (default: off in production)
- Major refactors that change behavior (gradual rollout)
- Integrations with external services (kill switch)
- NOT: bug fixes, internal refactors, or non-behavioral changes