9.5 KiB
name, description
| name | description |
|---|---|
| feature-flag-manager | Adds feature flag support using LaunchDarkly or JSON-based configuration to toggle features in UI components and Server Actions. This skill should be used when implementing feature flags, feature toggles, progressive rollouts, A/B testing, or gating functionality behind configuration. Use for feature flags, feature toggles, LaunchDarkly integration, progressive rollout, canary releases, or conditional features. |
Feature Flag Manager
Implement comprehensive feature flag management for controlled feature rollouts and A/B testing in worldbuilding applications.
Overview
To add feature flag capabilities:
- Choose between LaunchDarkly (cloud service) or JSON-based (local) implementation
- Set up feature flag provider with configuration
- Create feature flag components and hooks
- Gate UI components and Server Actions behind flags
- Implement user targeting and progressive rollouts
Implementation Options
LaunchDarkly Integration
To integrate LaunchDarkly:
- Install LaunchDarkly SDK:
npm install launchdarkly-react-client-sdk - Configure provider in app root with client-side ID
- Create hooks for flag evaluation
- Wrap components with feature flag checks
- Configure flags in LaunchDarkly dashboard
Use scripts/setup_launchdarkly.py to scaffold LaunchDarkly configuration.
JSON-Based Feature Flags
To implement local JSON-based flags:
- Create
config/feature-flags.jsonwith flag definitions - Build feature flag provider context
- Create hooks to read flags from context
- Implement environment-specific overrides
- Support runtime flag updates
Use scripts/setup_json_flags.py to generate JSON flag structure.
Consult references/feature-flag-patterns.md for implementation patterns and best practices.
Feature Flag Provider Setup
LaunchDarkly Provider
To set up LaunchDarkly in Next.js:
// app/providers.tsx
import { LDProvider } from 'launchdarkly-react-client-sdk';
export function Providers({ children }: { children: React.ReactNode }) {
return (
<LDProvider
clientSideID={process.env.NEXT_PUBLIC_LD_CLIENT_ID}
user={{
key: 'user-id',
email: 'user@example.com',
}}
>
{children}
</LDProvider>
);
}
JSON Provider
To create custom JSON provider:
// lib/feature-flags/provider.tsx
import { createContext, useContext } from 'react';
import flags from '@/config/feature-flags.json';
const FeatureFlagContext = createContext(flags);
export function FeatureFlagProvider({ children }: { children: React.ReactNode }) {
return (
<FeatureFlagContext.Provider value={flags}>
{children}
</FeatureFlagContext.Provider>
);
}
export function useFeatureFlags() {
return useContext(FeatureFlagContext);
}
Reference assets/feature-flag-provider.tsx for complete provider implementation.
Using Feature Flags
Component Gating
To gate UI components behind flags:
import { useFeatureFlag } from '@/lib/feature-flags';
export function NewFeatureComponent() {
const isEnabled = useFeatureFlag('new-timeline-view');
if (!isEnabled) {
return null;
}
return <div>New Timeline View</div>;
}
Conditional Rendering
To show different variants based on flags:
export function EntityList() {
const useNewLayout = useFeatureFlag('entity-list-redesign');
return useNewLayout ? <NewEntityList /> : <LegacyEntityList />;
}
Server Action Gating
To gate Server Actions:
// app/actions/entity-actions.ts
'use server';
import { getFeatureFlag } from '@/lib/feature-flags/server';
export async function createEntity(data: EntityData) {
const allowBulkCreate = await getFeatureFlag('bulk-entity-creation');
if (allowBulkCreate && data.items?.length > 1) {
return bulkCreateEntities(data.items);
}
return createSingleEntity(data);
}
Reference assets/server-actions-with-flags.ts for server-side flag patterns.
Flag Configuration
Flag Structure
Define flags with metadata:
{
"flags": {
"new-timeline-view": {
"enabled": true,
"description": "Enable new timeline visualization",
"rolloutPercentage": 100,
"allowedUsers": [],
"environments": {
"development": true,
"staging": true,
"production": false
}
}
}
}
Flag Types
Support different flag types:
- Boolean: Simple on/off toggle
- Percentage: Gradual rollout (0-100%)
- User Targeting: Specific users or groups
- Multivariate: Multiple variations (A/B/C testing)
Consult references/flag-types.md for detailed flag type specifications.
Progressive Rollout
To implement gradual feature rollouts:
- Initial Release: Enable for 5% of users
- Monitor Metrics: Track performance and errors
- Increase Rollout: Gradually increase to 25%, 50%, 100%
- Full Release: Enable for all users
- Remove Flag: Clean up flag code after stable release
Use scripts/rollout_manager.py to automate rollout percentage updates.
User Targeting
To target specific user segments:
By User ID
const flags = evaluateFlags(userId, flagConfig);
By User Properties
const flags = evaluateFlags({
userId: 'user-123',
email: 'user@example.com',
role: 'admin',
tier: 'premium',
});
By Custom Rules
const flags = evaluateFlags(user, {
rules: [
{ property: 'role', operator: 'equals', value: 'admin' },
{ property: 'tier', operator: 'in', values: ['premium', 'enterprise'] },
],
});
Environment-Specific Flags
To configure flags per environment:
{
"flags": {
"debug-mode": {
"development": true,
"staging": true,
"production": false
},
"experimental-features": {
"development": true,
"staging": false,
"production": false
}
}
}
Load environment-specific configuration at build time or runtime.
A/B Testing
To implement A/B tests:
export function EntityDetailPage() {
const variant = useFeatureFlagVariant('entity-detail-layout', {
control: 'grid',
variantA: 'list',
variantB: 'cards',
});
return variant === 'list' ? (
<EntityListView />
) : variant === 'cards' ? (
<EntityCardView />
) : (
<EntityGridView />
);
}
Track variant exposure for analytics:
useEffect(() => {
trackExposure('entity-detail-layout', variant);
}, [variant]);
Flag Lifecycle Management
Creating New Flags
To add a new feature flag:
- Define flag in configuration with metadata
- Set initial state (usually disabled)
- Implement flag checks in code
- Deploy with flag disabled
- Enable flag via dashboard or config update
Removing Old Flags
To clean up completed feature flags:
- Ensure flag is at 100% rollout
- Verify no incidents for 2+ weeks
- Remove flag checks from code
- Make flagged code permanent
- Remove flag from configuration
- Deploy cleanup changes
Use scripts/find_flag_usage.py to locate all usages of a flag before removal.
Testing with Feature Flags
Local Development
To override flags in development:
// .env.local
NEXT_PUBLIC_FEATURE_FLAGS_OVERRIDE='{"new-timeline-view":true}'
Testing Specific Variants
To test flag variations:
// test/setup.ts
import { mockFeatureFlags } from '@/lib/feature-flags/testing';
beforeEach(() => {
mockFeatureFlags({
'new-timeline-view': true,
'bulk-entity-creation': false,
});
});
Reference assets/testing-utils.ts for testing utilities.
Monitoring and Analytics
To track feature flag impact:
- Exposure Tracking: Log when flags are evaluated
- Performance Metrics: Monitor performance per variant
- Error Rates: Track errors by flag state
- User Engagement: Measure feature usage
- Conversion Metrics: Track business metrics per variant
Integrate with analytics platform:
import { analytics } from '@/lib/analytics';
export function useFeatureFlagWithTracking(flagName: string) {
const isEnabled = useFeatureFlag(flagName);
useEffect(() => {
analytics.track('feature_flag_exposure', {
flag: flagName,
enabled: isEnabled,
});
}, [flagName, isEnabled]);
return isEnabled;
}
LaunchDarkly-Specific Features
To leverage LaunchDarkly capabilities:
- Targeting Rules: Create complex targeting rules in dashboard
- Flag Triggers: Automate flag changes based on metrics
- Scheduled Rollouts: Plan feature releases in advance
- Flag Dependencies: Define flag prerequisites
- Audit Logs: Track all flag changes
- Team Workflows: Require approvals for production changes
Consult LaunchDarkly documentation for advanced features.
Best Practices
- Short-Lived Flags: Remove flags after rollout completes
- Clear Naming: Use descriptive, consistent flag names
- Documentation: Document flag purpose and timeline
- Default Values: Provide safe defaults for missing flags
- Testing: Test both enabled and disabled states
- Monitoring: Track flag performance and errors
- Cleanup: Regularly audit and remove unused flags
Troubleshooting
Common issues:
- Flag Not Updating: Check cache settings and invalidation
- Inconsistent State: Verify flag evaluation consistency
- Performance Impact: Minimize flag evaluation overhead
- Testing Challenges: Use proper mocking in tests
- Configuration Conflicts: Ensure environment-specific overrides work correctly