Best Practices
Follow these best practices to implement feature flags effectively and avoid common pitfalls. These guidelines will help you build a robust feature flag system that scales with your application.
Feature Flag Naming
Use Descriptive Names
// ✅ Good naming
'new-checkout-flow'
'beta-features'
'admin-panel-v2'
'pricing-page-redesign'
// ❌ Avoid
'flag1'
'new-feature'
'test-flag'
'feature-123'
Use Consistent Patterns
// ✅ Group related flags with prefixes
'checkout.new-flow'
'checkout.express-payment'
'checkout.guest-checkout'
// ✅ Use prefixes for different types
'landing.new-hero-section'
'config.max-retries' // Configuration
'beta.new-features' // Beta features
// ✅ Use versions for flags that are updated frequently
'checkout.new-flow.v1'
'checkout.new-flow.v2'
Avoid Environment-Specific Names
// ❌ Don't include environment in flag names
'beta-feature-dev'
'beta-feature-prod'
// ✅ Use environment-agnostic names
'beta-feature'
Performance Optimization
Efficient Flag Evaluation
// Use batch evaluation for multiple flags
const multipleFlags = async user => {
const flags = await client.getFeatures(
{
'beta-feature-a': false,
'beta-feature-b': false,
'beta-feature-c': false,
},
{
context: user,
},
)
return flags
}
Security Considerations
Client-Side vs Server-Side
// Client-side (API key)
const client = new SupaClient('public-client-key')
// Can only read flags, cannot modify
// Server-side (API key)
const client = new SupaClient('private-server-key')
// Full access to all operations
Common Anti-Patterns
Don’t Use Flags for Everything
// ❌ Don't use flags for everything
if (isFeatureEnabled('show-button')) {
return <Button />
}
// ✅ Use flags for meaningful features
if (isFeatureEnabled('new-checkout-flow')) {
return <NewCheckout />
} else {
return <OldCheckout />
}
Don’t Nest Flags Deeply
// ❌ Don't nest flags deeply
if (isFeatureEnabled('feature-a')) {
if (isFeatureEnabled('feature-b')) {
if (isFeatureEnabled('feature-c')) {
// Complex nested logic
}
}
}
// ✅ Use a single flag for complex features
if (isFeatureEnabled('advanced-feature-set')) {
// Handle all advanced features together
}
Don’t Forget Cleanup
// ❌ Don't leave flags forever
if (isFeatureEnabled('old-feature')) {
// This will never be cleaned up
}
// ✅ Set expiration and cleanup
const flagConfig = {
name: 'temporary-feature',
expirationDate: '2024-03-01',
cleanupPlan: 'Remove after full rollout',
}
Last updated on