feature-flags
Skill1 starsChanged 7 months agoMITView on GitHub
Feature flag design, lifecycle management, and progressive rollout strategies. Use when: adding feature toggles to gate new functionality, implementing gradual rollouts, designing A/B experiments, managing flag lifecycle and cleanup, auditing an existing codebase for stale flags, or choosing between flag implementations. Covers flag types, evaluation strategies, rollout patterns, flag hygiene, and testing with flags.
20 other projects use a version of this.
Adopted by
Most recently taken up by
- Cure-Consulting-Group/ProductEngineeringSkillstheir own version, first seen Nov 4, 2026
- primer/reacttheir own version, first seen Nov 1, 2026
- MiguelSavignano/claude-code-systemtheir own version, first seen Nov 1, 2026
- macro-inc/macrotheir own version, first seen Oct 25, 2026
- jars-demo/jars-skillstheir own version, first seen Oct 25, 2026
- vindreshsingh/engineering-skillstheir own version, first seen Oct 20, 2026
Used with
Projects with it also use background-jobs, rate-limiting and 6 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
YepAPISkillbackground-jobs
Queue workers with BullMQ/Inngest/Trigger.dev, job retries, dead letter queues, concurrency.
Also in 3 projects that use this
harperaaSkillrate-limiting
Implement rate limiting to prevent brute force attacks, spam, and resource abuse. Use this skill when you need to protect endpoints from automated attacks, prevent API abuse, limit request frequency, or control infrastructure costs. Triggers include "rate limiting", "rate limit", "brute force", "prevent spam", "API abuse", "resource exhaustion", "DoS", "withRateLimit", "too many requests", "429 error".
Also in 3 projects that use this
wpankSkillcaching
Caching strategies, invalidation, eviction policies, HTTP caching, distributed caching, and anti-patterns. Use when designing cache layers, choosing eviction policies, debugging stale data, or optimizing read-heavy workloads.
Also in 3 projects that use this
JohnJBorenSkillci-cd
CI/CD pipeline design, GitHub Actions, testing automation, and deployment strategies
Also in 4 projects that use this
OpenAISkillobservability
Vercel Observability expert guidance — Drains (logs, traces, speed insights, web analytics), Web Analytics, Speed Insights, runtime logs, custom events, OpenTelemetry integration, and monitoring dashboards. Use when instrumenting, debugging, or optimizing application performance and user experience on Vercel.
Also in 6 projects that use this
AnthropicSkillincident-response
Run an incident response workflow — triage, communicate, and write postmortem. Trigger with "we have an incident", "production is down", an alert that needs severity assessment, a status update mid-incident, or when writing a blameless postmortem after resolution.
Also in 5 projects that use this
Other versions20 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 20
- react/react★ 252ksame name
- facebook/react★ 252ksame name
- getsentry/sentry★ 46ksame name
- redis/RedisInsight★ 8.9ksame name
- BuilderIO/agent-native★ 7.6ksame name
- macro-inc/macro★ 6ksame name
- primer/react★ 3.9ksame name
- marcus/sidecar★ 1.1ksame name
- kid-sid/claude-spellbook★ 190same name
- irahardianto/awesome-agv★ 157same name
10 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository42 other files it gives its agents.
- accessibility-testingSkill
- alternatives-analysisSkill
- anomaly-detectionSkill
- api-designSkill
- async-messagingSkill
- caching-strategiesSkill
- chartsSkill
- cicdSkill
- code-reviewSkill
- commsSkill
- critical-feedbackSkill
- data-analysisSkill
- databaseSkill
- data-migrationsSkill
- data-visualizationSkill
- dependency-managementSkill
- dockerSkill
- error-handlingSkill
- git-workflowSkill
- goalsSkill
- ide-setupSkill
- large-changeSkill
- logging-metricsSkill
- markdown-docsSkill
- mcp-serverSkill
- meeting-agendasSkill
- okrsSkill
- presentationsSkill
- product-managementSkill
- prompt-writingSkill
- pythonSkill
- reclassificationSkill
- release-managementSkill
- retrospectivesSkill
- roadmap-planningSkill
- securitySkill
- stakeholder-commsSkill
- statisticsSkill
- status-updatesSkill
- testingSkill
- ticket-writingSkill
- typescriptSkill
The file
We split this skill into the rules it gives an agent
11 rules. 0 are common, 10 are distinctive, and 1 is very specific to this project.
0
Common
Most of the 17 edited versions we read keep these.
10
Distinctive
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 48
Release flags: Remove within 2 weeks of full rollout.
- Distinctive: line 49
Experiment flags: Remove when experiment concludes and winner is implemented.
- Distinctive: line 187
Default off: If the flag system is unavailable, features default to off (safe fallback).
- Distinctive: line 209
Error rate: No increase for flagged users vs control.
- Distinctive: line 263
Cons: No built-in UI, percentage rollout requires custom logic.
- Distinctive: line 321
Remove a flag when:
- Distinctive: line 330
Remove losing code path: Delete the old implementation.
- Distinctive: line 331
Remove flag definition: Delete from config/flag service.
- Distinctive: line 346
Weekly: Check for flags past their planned removal date.
- Very specific: line 370
No generic names (flag-1, test, new-feature).
- Distinctive: line 392
When auditing an existing codebase for feature flag practices:
“Common” is measured: kept by at least 6 in 10 of the 17 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Feature Flags
When to Use
- Gating new functionality behind a flag for gradual rollout
- Implementing A/B experiments or percentage-based rollouts
- Decoupling deployment from release (deploy dark, enable later)
- Building kill switches for risky features
- Managing long-running feature branches without merge conflicts
- Designing flag evaluation for server-side and client-side use
- Auditing an existing codebase for stale or orphaned flags
- Cleaning up flags after full rollout
Core Principle: Flags Are Temporary
Every flag has a planned removal date. Flags that live forever become tech debt — invisible branching logic that no one understands. Ship the feature, verify it works, remove the flag.
Flag Types
| Type | Lifespan | Example | Owner |
| Release | Days to weeks | Gate new checkout flow for gradual rollout | Engineering |
| Experiment | Weeks to months | A/B test pricing page layout | Product |
| Ops | Permanent (rare) | Kill switch for expensive feature under load | Engineering |
| Permission | Permanent | Feature only for enterprise tier customers | Product |
Rules
- Release flags: Remove within 2 weeks of full rollout.
- Experiment flags: Remove when experiment concludes and winner is implemented.
- Ops flags: Review quarterly — convert to config if permanent.
- Permission flags: These are entitlements, not feature flags. Model in authorization system if they grow complex.
Flag Schema
Flag Definition
interface FeatureFlag {
key: string; // Unique identifier: "checkout-v2"
description: string; // What this flag controls
type: "release" | "experiment" | "ops" | "permission";
owner: string; // Team or person responsible
createdAt: string; // ISO date
plannedRemovalDate: string; // When to clean up (required for release/experiment)
defaultValue: boolean; // Value when flag system is unavailable
rules: FlagRule[]; // Evaluation rules (ordered, first match wins)
}
interface FlagRule {
condition: FlagCondition;
value: boolean | string; // Boolean for toggles, string for variants
}
type FlagCondition =
| { type: "percentage"; value: number } // 0-100 rollout percentage
| { type: "user_ids"; value: string[] } // Specific users
| { type: "attribute"; key: string; value: string } // User attribute match
| { type: "environment"; value: string } // "production", "staging"
| { type: "default" };Flag Configuration (JSON)
{
"checkout-v2": {
"description": "New checkout flow with saved payment methods",
"type": "release",
"owner": "payments-team",
"createdAt": "2025-01-15",
"plannedRemovalDate": "2025-02-15",
"defaultValue": false,
"rules": [
{ "condition": { "type": "environment", "value": "staging" }, "value": true },
{ "condition": { "type": "user_ids", "value": ["internal-tester-1", "internal-tester-2"] }, "value": true },
{ "condition": { "type": "percentage", "value": 10 }, "value": true },
{ "condition": { "type": "default" }, "value": false }
]
}
}Evaluation
Server-Side (Python)
import hashlib
from typing import Any
def evaluate_flag(flag_key: str, user_id: str, attributes: dict[str, Any]) -> bool:
"""Evaluate a feature flag for a specific user."""
flag = get_flag_config(flag_key)
if flag is None:
return False # Flag not found — default off
for rule in flag["rules"]:
condition = rule["condition"]
if condition["type"] == "environment":
if get_environment() == condition["value"]:
return rule["value"]
elif condition["type"] == "user_ids":
if user_id in condition["value"]:
return rule["value"]
elif condition["type"] == "attribute":
if attributes.get(condition["key"]) == condition["value"]:
return rule["value"]
elif condition["type"] == "percentage":
# Deterministic: same user always gets same result for same flag
hash_input = f"{flag_key}:{user_id}"
hash_value = int(hashlib.sha256(hash_input.encode()).hexdigest()[:8], 16)
bucket = hash_value % 100
if bucket < condition["value"]:
return rule["value"]
elif condition["type"] == "default":
return rule["value"]
return flag["defaultValue"]Client-Side (React)
import { createContext, useContext } from "react";
import type { ReactNode } from "react";
interface FlagContextValue {
flags: Record<string, boolean>;
}
const FlagContext = createContext<FlagContextValue>({ flags: {} });
function FlagProvider({ children, flags }: { children: ReactNode; flags: Record<string, boolean> }) {
return <FlagContext.Provider value={{ flags }}>{children}</FlagContext.Provider>;
}
function useFlag(key: string): boolean {
const { flags } = useContext(FlagContext);
return flags[key] ?? false;
}
// Usage in component
function CheckoutPage() {
const useNewCheckout = useFlag("checkout-v2");
if (useNewCheckout) {
return <NewCheckoutFlow />;
}
return <LegacyCheckoutFlow />;
}Evaluation Rules
- Deterministic: Same user + same flag = same result. Use hash-based bucketing, not random.
- First match wins: Rules are evaluated in order. Put specific rules (user IDs, environments) before percentage rules.
- Default off: If the flag system is unavailable, features default to off (safe fallback).
- Server-authoritative: Client receives pre-evaluated flags from the server. Never send flag rules to the client.
Rollout Strategies
Gradual Percentage Rollout
Day 1: 0% → 5% (internal team + canary users)
Day 2: 5% → 10% (monitor error rates, latency)
Day 3: 10% → 25% (monitor business metrics)
Day 5: 25% → 50% (compare A/B if experiment)
Day 7: 50% → 100% (full rollout)
Day 14: Remove flag (cleanup)Monitoring During Rollout
At each stage, verify:
- Error rate: No increase for flagged users vs control.
- Latency: P50/P95/P99 within acceptable bounds.
- Business metrics: Conversion rate, revenue per user, engagement.
- User feedback: Support tickets, rage clicks, session recordings.
Rollback
If metrics degrade:
# Instant rollback: set percentage to 0
update_flag("checkout-v2", rules=[
{"condition": {"type": "default"}, "value": False},
])Rollback should take seconds, not minutes. This is the primary advantage of feature flags over code rollback.
Flag Storage
Simple: Config File (Small Projects)
// flags.json — committed, deployed with application
{
"checkout-v2": true,
"new-search": false
}Pros: Simple, version-controlled, no external dependency. Cons: Requires deploy to change. No gradual rollout.
Medium: SSM Parameter Store / DynamoDB
import boto3
import json
ssm = boto3.client("ssm")
def get_flags() -> dict[str, Any]:
"""Load flags from SSM Parameter Store."""
response = ssm.get_parameter(
Name="/myapp/prod/feature-flags",
WithDecryption=False,
)
return json.loads(response["Parameter"]["Value"])Pros: Change flags without deploying. Cheap. Simple. Cons: No built-in UI, percentage rollout requires custom logic.
Advanced: Dedicated Flag Service (LaunchDarkly, Unleash, Flagsmith)
Use when:
- Multiple teams manage their own flags.
- You need a UI for non-engineers to toggle flags.
- Sophisticated targeting (geo, device, plan tier) is required.
- Audit log of flag changes is mandatory.
Testing with Feature Flags
Unit Tests: Test Both Paths
import pytest
@pytest.mark.parametrize("flag_value", [True, False])
def test_checkout_flow(flag_value: bool, monkeypatch: pytest.MonkeyPatch) -> None:
"""Test both checkout flows regardless of current flag state."""
monkeypatch.setattr("features.evaluate_flag", lambda key, **kw: flag_value)
result = process_checkout(user_id="test-user", cart=sample_cart)
if flag_value:
assert result.flow == "v2"
else:
assert result.flow == "legacy"Integration Tests: Pin Flag Values
@pytest.fixture
def flags_all_on() -> dict[str, bool]:
"""Enable all feature flags for integration testing."""
return {"checkout-v2": True, "new-search": True}
@pytest.fixture
def flags_all_off() -> dict[str, bool]:
"""Disable all feature flags for integration testing."""
return {"checkout-v2": False, "new-search": False}E2E Tests: Test Current State
E2E tests should test the current production state of flags. Don't override flags in E2E — if a flag is on in production, test with it on.
Flag Cleanup
When to Remove
Remove a flag when:
- The feature is fully rolled out to 100% for at least 1 week.
- The experiment has concluded and the winning variant is hardcoded.
- The ops flag has been on for 6+ months and no one has toggled it.
Cleanup Process
- Verify: Confirm flag is at 100% (or permanently on) with no recent toggles.
- Remove evaluation calls: Replace
if flag("checkout-v2")with the winning branch. - Remove losing code path: Delete the old implementation.
- Remove flag definition: Delete from config/flag service.
- Commit: One commit per flag cleanup.
Detecting Stale Flags
# Find flag references in code
grep -r "checkout-v2" --include="*.py" --include="*.ts" --include="*.tsx" src/
# List flags with past planned removal dates
jq 'to_entries[] | select(.value.plannedRemovalDate < "2025-01-15") | .key' flags.jsonCleanup Cadence
- Weekly: Check for flags past their planned removal date.
- Monthly: Review all active flags — any that can be removed?
- Quarterly: Audit permanent ops/permission flags — still needed?
Flag Naming Convention
<domain>-<feature>[-<variant>]| Example | Type | Description |
checkout-v2 | Release | New checkout flow |
search-fuzzy-matching | Release | Enable fuzzy search |
pricing-annual-discount | Experiment | Test annual plan discount |
api-rate-limit-strict | Ops | Tighter rate limits under load |
plan-enterprise-analytics | Permission | Analytics for enterprise tier |
Rules:
- Lowercase, kebab-case.
- Domain prefix for grouping.
- Descriptive — someone unfamiliar should understand the purpose.
- No generic names (
flag-1,test,new-feature).
Anti-Patterns
| Anti-Pattern | Problem | Fix |
| Flag with no planned removal date | Lives forever, becomes invisible tech debt | Require removal date on creation for release/experiment flags |
Nested flags (if flag_a and flag_b) | Combinatorial explosion of states to test | Keep flags independent; one flag per feature |
| Flag evaluated differently in two places | Inconsistent behavior for the same user | Centralize evaluation; pass result as parameter |
| Client-side flag evaluation with rules | Exposes targeting logic and user segments | Server evaluates; client receives boolean result |
| Using flags instead of authorization | Flag system becomes a permissions system | Use proper RBAC/ABAC for entitlements |
| No monitoring during rollout | Degradation goes unnoticed until 100% | Define monitoring criteria before enabling |
| Random-based percentage rollout | Same user gets different experience on each request | Use hash-based deterministic bucketing |
| Flag config not version-controlled | No history of who changed what, when | Store in git or use a flag service with audit log |
| Monster flag guarding 500 lines | Too much code behind one toggle | Break into smaller flags or defer merge until feature is complete |
Audit Checklist
When auditing an existing codebase for feature flag practices:
- Every flag has a documented owner and description
- Release and experiment flags have a planned removal date
- No flags past their planned removal date exist in the codebase
- Flag evaluation is centralized (single function/hook, not ad-hoc checks)
- Percentage-based rollout uses deterministic hashing, not random
- Both code paths (flag on and off) are tested
- Client-side flags are pre-evaluated by the server
- Monitoring criteria defined before enabling a flag in production
- Gradual rollout follows staged percentage increases
- Flag changes are logged with who, when, and why
- No nested or dependent flag conditions
- Cleanup process exists and runs at least monthly
- Flag naming follows a consistent convention
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

