Feature Flags
This skill guides developers in implementing and managing React feature flags.
Install
npx promptshop add feature-flagsDetails
What This Skill Does
This skill guides developers in implementing and managing React feature flags. It provides instructions on how to add new flags, gate tests, check flag states across different channels, and debug channel-specific failures. This allows for controlled rollout of new features and A/B testing.
When to Use
- Rolling out new features gradually.
- Performing A/B testing.
- Enabling features for specific user groups.
- Disabling buggy features quickly.
- Testing experimental features in production.
- Managing different feature sets across channels.
Key Features
- Manages feature flags in React applications.
- Supports multiple flag files for different channels.
- Offers
@gatepragma for test-level gating. - Includes
gate()inline for assertion-level gating. - Provides
/flagscommand to view flag states. - Handles
__VARIANT__flags for gatekeeper simulations.
Manual Installation
React Feature Flags
Flag Files
| File | Purpose |
|---|---|
| packages/shared/ReactFeatureFlags.js | Default flags (canary), EXPERIMENTAL overrides |
| packages/shared/forks/ReactFeatureFlags.www.js | www channel, VARIANT overrides |
| packages/shared/forks/ReactFeatureFlags.native-fb.js | React Native, VARIANT overrides |
| packages/shared/forks/ReactFeatureFlags.test-renderer.js | Test renderer |
Gating Tests
@gate pragma (test-level)
Use when the feature is completely unavailable without the flag:
// @gate enableViewTransition it('supports view transitions', () => { // This test only runs when enableViewTransition is true // and is SKIPPED (not failed) when false });
gate() inline (assertion-level)
Use when the feature exists but behavior differs based on flag:
it('renders component', async () => { await act(() => root.render(<App />));
if (gate(flags => flags.enableNewBehavior)) { expect(container.textContent).toBe('new output'); } else { expect(container.textContent).toBe('legacy output'); } });
Adding a New Flag
Add to ReactFeatureFlags.js with default value Add to each fork file (.www.js, .native-fb.js, etc.) If it should vary in www/RN, set to VARIANT in the fork file Gate tests with @gate flagName or inline gate()
Checking Flag States
Use /flags to view states across channels. See the flags skill for full command options.
VARIANT Flags (GKs)
Flags set to VARIANT simulate gatekeepers - tested twice (true and false):
/test www <pattern> # VARIANT = true /test www variant false <pattern> # VARIANT = false
Debugging Channel-Specific Failures
Run /flags --diff to compare values Check @gate conditions - test may be gated to specific channels Run /test to isolate the failure Verify flag exists in all fork files if newly added
Common Mistakes
Forgetting both variants - Always test www AND www variant false for VARIANT flags Using @gate for behavior differences - Use inline gate() if both paths should run Missing fork files - New flags must be added to ALL fork files, not just the main one Wrong gate syntax - It's gate(flags => flags.name), not gate('name')
React Feature Flags
Flag Files
| File | Purpose |
|---|---|
| packages/shared/ReactFeatureFlags.js | Default flags (canary), EXPERIMENTAL overrides |
| packages/shared/forks/ReactFeatureFlags.www.js | www channel, VARIANT overrides |
| packages/shared/forks/ReactFeatureFlags.native-fb.js | React Native, VARIANT overrides |
| packages/shared/forks/ReactFeatureFlags.test-renderer.js | Test renderer |
Gating Tests
@gate pragma (test-level)
Use when the feature is completely unavailable without the flag:
// @gate enableViewTransition it('supports view transitions', () => { // This test only runs when enableViewTransition is true // and is SKIPPED (not failed) when false });
gate() inline (assertion-level)
Use when the feature exists but behavior differs based on flag:
it('renders component', async () => { await act(() => root.render(<App />));
if (gate(flags => flags.enableNewBehavior)) { expect(container.textContent).toBe('new output'); } else { expect(container.textContent).toBe('legacy output'); } });
Adding a New Flag
Add to ReactFeatureFlags.js with default value Add to each fork file (.www.js, .native-fb.js, etc.) If it should vary in www/RN, set to VARIANT in the fork file Gate tests with @gate flagName or inline gate()
Checking Flag States
Use /flags to view states across channels. See the flags skill for full command options.
VARIANT Flags (GKs)
Flags set to VARIANT simulate gatekeepers - tested twice (true and false):
/test www <pattern> # VARIANT = true /test www variant false <pattern> # VARIANT = false
Debugging Channel-Specific Failures
Run /flags --diff to compare values Check @gate conditions - test may be gated to specific channels Run /test to isolate the failure Verify flag exists in all fork files if newly added
Common Mistakes
Forgetting both variants - Always test www AND www variant false for VARIANT flags Using @gate for behavior differences - Use inline gate() if both paths should run Missing fork files - New flags must be added to ALL fork files, not just the main one Wrong gate syntax - It's gate(flags => flags.name), not gate('name')