Feature Flags
Feature flags are the core component of DarkFeature that allow you to control feature availability and behavior without code deployments. This guide covers how to create, configure, and use feature flags effectively.
What are Feature Flags?
Feature flags (also called feature toggles) are controls that determine whether a feature is enabled or disabled for specific users or environments. They enable:
- Safe Deployments - Deploy code without activating features
- Gradual Rollouts - Release features to a percentage of users
- Kill Switches - Quickly disable problematic features
- Environment Management - Different settings across environments
Creating Feature Flags
Step 1: Create a New Flag
- Navigate to the Features section in your dashboard
- Click “Create Feature”
- Enter a descriptive name (e.g., “new-navigation”)
- Add an optional description
- Choose the flag type (Boolean, String, Number, JSON)
- Click “Create Feature”
Step 2: Configure Settings
After creating a flag, configure its settings:
- Default Value - The value when no targeting rules match
- Targeting Rules - Conditions that determine when the flag is enabled
- Percentage Rollout - Gradually increase feature exposure
- Environment Settings - Different configurations per environment
Step 3: Set Up Targeting
Configure who sees the feature:
// Example targeting rules
{
"rules": [
{
"condition": "user.email contains '@admin.com'",
"value": true
},
{
"condition": "user.plan equals 'premium'",
"value": true
}
],
"defaultValue": false
}
Flag Types
Boolean Flags
Simple on/off switches for feature control.
import { DarkFeatureClient } from '@darkfeature/sdk-javascript'
const client = new DarkFeatureClient({
apiKey: '1234567890abcdef1234567890abcdef',
context: { userId: '123' },
})
// Check if feature is enabled
const isEnabled = await client.getFeature('new-navigation', { fallback: false })
if (isEnabled) {
showNewNavigation()
} else {
showOldNavigation()
}
String Flags
Return string values for configuration or content.
// Get string value
const theme = await client.getFeature('theme', { fallback: 'light' })
// Use in your application
document.body.className = `theme-${theme}`
Number Flags
Return numeric values for configuration settings.
// Get numeric value
const maxRetries = await client.getFeature('max-retries', { fallback: 3 })
// Use in your application
for (let i = 0; i < maxRetries; i++) {
// Retry logic
}
JSON Flags
Return complex objects for advanced configurations.
// Get JSON configuration
const config = await client.getFeature('api-config', {
fallback: {
timeout: 5000,
retries: 3,
endpoints: ['/api/v1', '/api/v2'],
},
})
// Use in your application
const apiClient = new ApiClient(config)
Targeting Rules
User Attributes
Target users based on their properties:
// Target by email domain
{
"condition": "user.email contains '@company.com'",
"value": true
}
// Target by user plan
{
"condition": "user.plan equals 'premium'",
"value": true
}
// Target by location
{
"condition": "user.country equals 'US'",
"value": true
}
Percentage Rollouts
Gradually roll out features to increasing percentages:
// Configure percentage rollout in the dashboard
// The platform automatically handles percentage-based targeting
const isEnabled = await client.getFeature('new-feature', { fallback: false })
if (isEnabled) {
showNewFeature()
} else {
showOldFeature()
}
Complex Rules
Combine multiple conditions with logical operators:
{
"rules": [
{
"condition": "user.plan equals 'premium' AND user.country equals 'US'",
"value": true
},
{
"condition": "user.email contains '@admin.com' OR user.role equals 'admin'",
"value": true
}
],
"defaultValue": false
}
Environment Management
Environment-Specific Settings
Configure different flag states across environments:
- Development - Enable for testing
- Staging - Enable for validation
- Production - Control rollout percentage
Environment Variables
Use environment variables for configuration:
# Development
export DARKFEATURE_ENV="development"
# Staging
export DARKFEATURE_ENV="staging"
# Production
export DARKFEATURE_ENV="production"
// Use environment-specific API keys
const client = new DarkFeatureClient({
apiKey: process.env.DARKFEATURE_API_KEY,
context: { userId: '123' },
})
Using Feature Flags
Basic Usage
import { DarkFeatureClient } from '@darkfeature/sdk-javascript'
const client = new DarkFeatureClient({
apiKey: '1234567890abcdef1234567890abcdef',
context: { userId: '123' },
})
// Simple boolean check
const isEnabled = await client.getFeature('new-navigation', { fallback: false })
if (isEnabled) {
renderNewNavigation()
} else {
renderOldNavigation()
}
With Context Override
// Override context for specific requests
const isEnabled = await client.getFeature('premium-features', {
fallback: false,
context: { plan: 'premium' },
})
Multiple Features
// Get multiple features efficiently
const features = await client.getFeatures({
features: {
'new-navigation': false,
'dark-mode': false,
'premium-features': false,
},
context: { userId: '123' },
})
if (features['new-navigation']) {
applyNewNavigation()
}
if (features['dark-mode']) {
applyDarkTheme()
}
if (features['premium-features']) {
showPremiumFeatures()
}
React Integration
import { DarkFeatureProvider, useFeature } from '@darkfeature/sdk-react'
function App() {
return (
<DarkFeatureProvider
config={{
apiKey: '1234567890abcdef1234567890abcdef',
context: { userId: '123' },
}}>
<MyComponent />
</DarkFeatureProvider>
)
}
function MyComponent() {
const { feature: isEnabled } = useFeature('new-navigation', {
fallback: false,
})
return isEnabled ? <NewNavigation /> : <OldNavigation />
}
Server-Side Integration
import { DarkFeatureClient } from '@darkfeature/sdk-javascript'
const client = new DarkFeatureClient({
apiKey: process.env.DARKFEATURE_API_KEY,
context: { userId: '123' },
})
// Express.js middleware
app.use(async (req, res, next) => {
const context = {
userId: req.user?.id,
email: req.user?.email,
}
req.features = await client.getFeatures({
features: {
'new-navigation': false,
'premium-features': false,
},
context,
})
next()
})
Best Practices
Naming Conventions
- Use descriptive, lowercase names with hyphens
- Include the feature name and environment context
- Examples:
new-navigation
,beta-features
,dark-mode
Flag Lifecycle
- Development - Create and test flags locally
- Staging - Test flags in staging environment
- Production - Roll out flags to production users
- Cleanup - Remove flags when no longer needed
Testing
- Test flags in all environments
- Use feature flags in your test suite
- Mock flags for unit tests
- Test both enabled and disabled states
// Mock client for testing
class MockDarkFeatureClient {
constructor(mockFlags = {}) {
this.mockFlags = mockFlags
}
async getFeature(featureName, options = {}) {
return this.mockFlags[featureName] ?? options.fallback
}
}
const mockClient = new MockDarkFeatureClient({
'new-navigation': true,
'premium-features': false,
})
Error Handling
Always provide fallback values to ensure your application continues to work:
try {
const isEnabled = await client.getFeature('new-feature', { fallback: false })
// Use feature
} catch (error) {
console.error('Feature flag error:', error)
// Fallback to default behavior
showDefaultFeature()
}
Performance Optimization
- Use caching effectively
- Minimize API calls with batch requests
- Monitor evaluation times
- Use appropriate fallback values
// Batch multiple feature requests
const features = await client.getFeatures({
features: {
'feature-a': false,
'feature-b': false,
'feature-c': false,
},
context: { userId: '123' },
})
Monitoring and Analytics
Track Feature Usage
Monitor how your features are being used:
- Real-time metrics - Live feature usage data
- User engagement - Track how features affect behavior
- Performance monitoring - Monitor flag evaluation times
- Custom events - Track specific user actions
Dashboard Analytics
- View feature usage across environments
- Monitor targeting rule effectiveness
- Track performance metrics
- Export data for analysis
Next Steps
- Targeting Rules - Learn about advanced targeting techniques
- Analytics - Track and analyze feature usage
- Environments - Manage multiple environments
- Best Practices - Follow proven patterns