feature-flags

v2026.09.24

Feature flag management. LaunchDarkly, Unleash, Flagsmith, and custom implementations. Gradual rollouts, A/B testing, kill switches, and flag lifecycle management. USE WHEN: user mentions "feature flag", "feature toggle", "LaunchDarkly", "Unleash", "Flagsmith", "gradual rollout", "A/B test", "canary release", "kill switch" DO NOT USE FOR: CI/CD deployment strategies - use `github-actions`; environment config - use environment variable patterns

GitHub
安装命令
npx skhub add claude-dev-suite/feature-flags
Markdown
SKILL.md

Feature Flags

LaunchDarkly

import * as LaunchDarkly from '@launchdarkly/node-server-sdk';

const client = LaunchDarkly.init(process.env.LD_SDK_KEY!);
await client.waitForInitialization();

// Evaluate flag
const showNewUI = await client.variation('new-dashboard-ui', {
  key: user.id,
  email: user.email,
  custom: { plan: user.plan },
}, false); // default value

if (showNewUI) {
  renderNewDashboard();
} else {
  renderLegacyDashboard();
}

React SDK

import { useFlags, withLDProvider } from 'launchdarkly-react-client-sdk';

function Dashboard() {
  const { newDashboardUi, maxUploadSize } = useFlags();

  return newDashboardUi ? <NewDashboard maxUpload={maxUploadSize} /> : <LegacyDashboard />;
}

// Wrap app
export default withLDProvider({
  clientSideID: process.env.NEXT_PUBLIC_LD_CLIENT_ID!,
  context: { kind: 'user', key: user.id, email: user.email },
})(App);

Unleash (self-hosted)

import { initialize } from 'unleash-client';

const unleash = initialize({
  url: 'https://unleash.example.com/api',
  appName: 'my-app',
  customHeaders: { Authorization: process.env.UNLEASH_API_KEY! },
});

if (unleash.isEnabled('new-checkout', { userId: user.id })) {
  // New checkout flow
}

Custom Implementation (simple)

interface FeatureFlags {
  [key: string]: {
    enabled: boolean;
    rolloutPercentage?: number;
    allowedUsers?: string[];
  };
}

class FlagService {
  constructor(private flags: FeatureFlags) {}

  isEnabled(flag: string, userId?: string): boolean {
    const config = this.flags[flag];
    if (!config?.enabled) return false;
    if (config.allowedUsers?.includes(userId!)) return true;
    if (config.rolloutPercentage != null && userId) {
      const hash = simpleHash(userId + flag) % 100;
      return hash < config.rolloutPercentage;
    }
    return config.enabled;
  }
}

Flag Types

TypePurposeExample
BooleanOn/off togglenew-ui-enabled
Percentage rolloutGradual release10% → 50% → 100%
User targetingSpecific usersBeta testers, internal
MultivariateA/B/C testingcheckout-variant: "A"
Kill switchEmergency disablepayments-enabled

Anti-Patterns

Anti-PatternFix
Flags that live foreverSet expiration, clean up after full rollout
Flag checks deep in codeCheck at entry points, pass result down
No default valuesAlways provide sensible defaults
Testing only flagged-on pathTest both paths in CI
Flags in tight loopsCache flag evaluation result

Production Checklist

  • Default values for all flags (graceful degradation)
  • Flag naming convention (feature-name-action)
  • Cleanup process for fully-rolled-out flags
  • Monitoring: flag evaluation metrics
  • Testing both flag states in CI
  • Audit log of flag changes
发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.24

发布时间

Sep 24, 2026

分类

未分类

许可证

MIT

源路径

skills/best-practices/feature-flags

默认分支

main

最新提交

9496306

Tree SHA

fe4e2f1