Files
react/.claude/skills/feature-flags/SKILL.md
Ricky a0566250b2 [repo] init claude config (#35617)
## Overview

Adds a claude setup that works with the nested /compiler setup.

The constraints are:
- when working in the root repo, don't use the compiler configs (easy)
- when working in the compiler/ don't use the parent contigs (hard)

The first one is easy: there's a claude.md and .claude directory in
/compiler that is only loaded when you start a session from /compuler.
The second one is hard, because if you start a session from /compiler,
the parent claude files and skills are loaded.

I was able to deny the permissions to the parent skills in
settings.json, but the descriptions are still loaded into context and I
don't think that's avoidable.

To keep the parent claude file out of context, I created a hook hack: I
moved all the non-compiler claude file context to instructions.md and
added a SessionStart hook to cat the file into context if the cwd isn't
the /compiler. Works well, but won't show it as part of the `/context`
slash command.


## Skills

I also added a number of skills specific to the React repo:

| Skill | Description |
|-------|-------------|
| `/extract-errors` |  `yarn extract-errors` |
| `/feature-flags` | how feature flags work and `@gate`  |
| `/fix` | linc and prettier |
| `/flags` | `yarn flags` |
| `/flow` | `yarn flow <variant>` |
| `/test` | `yarn test-*` |
| `/verify` | `run all the lints/tests/flow to verify` |

### Example: Flow

| before | after |
|-----|-----|
| <img width="1076" height="442" alt="flow-before"
src="https://github.com/user-attachments/assets/73eec143-d0af-4771-b501-c9dc29cc09ac"
/> | <img width="1076" height="273" alt="flow-after"
src="https://github.com/user-attachments/assets/292d33af-1d98-4252-9c08-744b33e88b86"
/> |

### Example: Tests

| before | after |
|-----|-----|
| <img width="1048" height="607" alt="test-before"
src="https://github.com/user-attachments/assets/aa558ccf-2cee-4d22-b1f1-e4221c5a59dd"
/> | <img width="1075" height="359" alt="test-after"
src="https://github.com/user-attachments/assets/eb795392-6f46-403f-b9bb-8851ed790165"
/> |
2026-01-23 20:16:06 -05:00

2.6 KiB

name, description
name description
feature-flags Use when feature flag tests fail, flags need updating, understanding @gate pragmas, debugging channel-specific test failures, or adding new flags to React.

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

  1. Add to ReactFeatureFlags.js with default value
  2. Add to each fork file (*.www.js, *.native-fb.js, etc.)
  3. If it should vary in www/RN, set to __VARIANT__ in the fork file
  4. 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

  1. Run /flags --diff <channel1> <channel2> to compare values
  2. Check @gate conditions - test may be gated to specific channels
  3. Run /test <channel> <pattern> to isolate the failure
  4. 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')