
If you're working on React core and hit a test failure that only happens in the www channel or mysteriously skips in certain environments, this is your troubleshooting guide. It walks you through the fork file system (ReactFeatureFlags.js and its channel-specific variants), explains when to use @gate pragmas versus inline gate() checks, and covers the __VARIANT__ flag behavior that simulates gatekeeper testing. The debugging section on comparing flag states across channels is genuinely useful when you're staring at a CI failure that doesn't reproduce locally. One gotcha worth internalizing: feature flags need to exist in every fork file, not just the main one, which trips people up more than it should.
$ npx -y skills add facebook/react --skill feature-flags --agent claude-codeInstalls into .claude/skills of the current project.
| 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 |
@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');
}
});
ReactFeatureFlags.js with default value*.www.js, *.native-fb.js, etc.)__VARIANT__ in the fork file@gate flagName or inline gate()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
/flags --diff <channel1> <channel2> to compare values@gate conditions - test may be gated to specific channels/test <channel> <pattern> to isolate the failurewww AND www variant false for __VARIANT__ flagsgate() if both paths should rungate(flags => flags.name), not gate('name')Sponsors