feature-flag · git:20260614.2f67b30 · 2026-06-14 · sha256 07a394595fbb36bb
feature-flag git:20260614.2f67b30A
Immutable. This exact content is served forever at /api/v1/blob/07a394595fbb36bb.
---
name: feature-flag
description: Feature flag implementation, management, and cleanup. Handles flag creation, gradual rollout strategies, A/B testing wiring, stale flag detection, and safe flag removal. Supports LaunchDarkly, Unleash, GrowthBook, Statsig, custom env-var flags, and database-backed toggles. Use when adding gated features, rolling out gradually, or cleaning up old flags.
---
# Feature Flag
Implement, manage, and retire feature flags safely across any stack.
## Quick Start
```
/feature-flag add <name> — scaffold a new flag
/feature-flag rollout <name> 10% — set gradual rollout percentage
/feature-flag audit — find all flags + flag staleness
/feature-flag remove <name> — safe removal with dead-code cleanup
/feature-flag list — show all flags and current state
```
## Flag Types
| Type | When to Use |
|------|-------------|
| **Kill switch** | Turn off broken feature instantly in prod |
| **Release gate** | Ship code dark, enable when ready |
| **Gradual rollout** | 1% → 10% → 50% → 100% |
| **A/B experiment** | Split traffic, measure variant metrics |
| **User segment** | Beta users, internal users, region-specific |
## Workflow
### Add New Flag
Claude will:
1. Name-check (format: `snake_case`, category prefix: `feat_`, `exp_`, `ops_`)
2. Create flag definition in chosen provider or local config
3. Scaffold flag-gated code with proper `if/else` fallback
4. Add cleanup TODO with target removal date
5. Add to flag registry / CLAUDE.md
### Gradual Rollout
```
/feature-flag rollout feat_new_checkout 10%
/feature-flag rollout feat_new_checkout 50%
/feature-flag rollout feat_new_checkout 100%
/feature-flag promote feat_new_checkout — remove flag, keep code
```
### Audit Stale Flags
Finds flags that:
- Are 100% enabled and have no A/B experiment
- Were last modified > 90 days ago
- Control code paths never hit in production
## Code Patterns
### Environment variable (simplest)
```typescript
// flag-registry.ts
export const FLAGS = {
NEW_CHECKOUT: process.env.FLAG_NEW_CHECKOUT === 'true',
DARK_MODE_V2: process.env.FLAG_DARK_MODE_V2 === 'true',
} as const
// usage
if (FLAGS.NEW_CHECKOUT) {
return <NewCheckout />
}
return <OldCheckout />
```
### LaunchDarkly
```typescript
import { LDClient } from '@launchdarkly/node-server-sdk'
const flag = await client.variation('feat-new-checkout', user, false)
if (flag) { ... }
```
### GrowthBook
```typescript
const gb = new GrowthBook({ features })
if (gb.isOn('feat-new-checkout')) { ... }
```
### Database-backed (custom)
```sql
-- flags table
CREATE TABLE feature_flags (
key TEXT PRIMARY KEY,
enabled BOOLEAN DEFAULT false,
rollout_pct INT DEFAULT 0,
updated_at TIMESTAMPTZ DEFAULT now()
);
```
## Safe Flag Removal Checklist
```
[ ] Flag is 100% enabled in all environments
[ ] No A/B experiment data still being collected
[ ] Metrics confirmed (conversion, error rate, latency)
[ ] Remove flag check from code (keep the new path)
[ ] Delete flag from provider / config
[ ] Delete tests that mock the disabled path
[ ] Update changelog
```
## Naming Conventions
```
feat_<feature> — user-facing feature gate
exp_<hypothesis> — A/B experiment
ops_<operation> — operational kill switch
tmp_<migration> — temporary migration flag (max 30 days)
```
## Anti-Patterns
- Nesting flags inside flags (creates truth table hell)
- Flags with no owner or target removal date
- Testing only the enabled path (always test both)
- Keeping flags after 100% rollout > 2 weeks