Environments
Environments in DarkFeature allow you to manage different configurations across development, staging, and production. This ensures safe testing and deployment workflows.
What Are Environments?
Environments are isolated spaces where you can configure features differently. Each environment has its own set of flags, targeting rules, and configurations, allowing you to test safely before deploying to production.
// Environment-specific configuration
const environments = {
development: {
'new-feature': true, // Always enabled in dev
'beta-feature': true, // Always enabled in dev
'production-feature': false, // Disabled in dev
},
staging: {
'new-feature': true, // Test in staging
'beta-feature': false, // Disabled in staging
'production-feature': false, // Disabled in staging
},
production: {
'new-feature': false, // Disabled in production
'beta-feature': false, // Disabled in production
'production-feature': true, // Enabled in production
},
}
Default Environments
Development Environment
// Development environment configuration
const devConfig = {
name: 'development',
description: 'Local development and testing',
features: {
'new-feature': {
enabled: true,
targeting: {
rules: [
{
attribute: 'user.email',
operator: 'ends_with',
value: '@company.com',
},
],
},
},
},
}
Characteristics:
- Always enable new features for testing
- Target internal users only
- No production data
- Fast iteration cycles
Staging Environment
// Staging environment configuration
const stagingConfig = {
name: 'staging',
description: 'Pre-production testing',
features: {
'new-feature': {
enabled: true,
targeting: {
rules: [
{
attribute: 'user.email',
operator: 'ends_with',
value: '@company.com',
},
],
percentage: 50, // Test with 50% of internal users
},
},
},
}
Characteristics:
- Mirror production configuration
- Test with real data
- Gradual rollout testing
- Performance validation
Production Environment
// Production environment configuration
const prodConfig = {
name: 'production',
description: 'Live production environment',
features: {
'new-feature': {
enabled: false, // Start disabled
targeting: {
rules: [
{
attribute: 'user.plan',
operator: 'equals',
value: 'premium',
},
],
percentage: 5, // Start with 5% rollout
},
},
},
}
Characteristics:
- Conservative feature rollouts
- Real user data
- Performance critical
- Safety first approach
Environment Management
Creating Custom Environments
// Custom environment configuration
const customEnv = {
name: 'beta-testing',
description: 'Beta user testing environment',
features: {
'new-feature': {
enabled: true,
targeting: {
rules: [
{
attribute: 'user.tags',
operator: 'contains',
value: 'beta-tester',
},
],
},
},
},
}
Environment Inheritance
// Inherit from production environment
const stagingEnv = {
name: 'staging',
inheritFrom: 'production',
overrides: {
'new-feature': {
enabled: true, // Override production setting
targeting: {
percentage: 100, // Enable for all staging users
},
},
},
}
Environment-Specific SDK Configuration
Client-Side Configuration
// Environment-aware SDK initialization
const getEnvironment = () => {
if (window.location.hostname === 'localhost') {
return 'development'
} else if (window.location.hostname === 'staging.example.com') {
return 'staging'
} else {
return 'production'
}
}
const df = new DarkFeature('your-key', {
environment: getEnvironment(),
// Environment-specific options
development: {
debug: true,
cacheTimeout: 0,
},
staging: {
debug: true,
cacheTimeout: 30000,
},
production: {
debug: false,
cacheTimeout: 300000,
},
})
Server-Side Configuration
// Node.js environment configuration
const df = new DarkFeature('your-key', {
environment: process.env.NODE_ENV || 'development',
// Environment-specific settings
development: {
logLevel: 'debug',
cacheEnabled: false,
},
staging: {
logLevel: 'info',
cacheEnabled: true,
cacheTimeout: 30000,
},
production: {
logLevel: 'error',
cacheEnabled: true,
cacheTimeout: 300000,
},
})
Environment Workflows
Development Workflow
// Development workflow
const devWorkflow = {
steps: [
'Create feature flag in development',
'Enable flag for internal testing',
'Test with development data',
'Iterate and refine',
'Deploy to staging',
],
}
// Development helper functions
const isDevelopment = () => process.env.NODE_ENV === 'development'
const getDevFeature = (featureKey, defaultValue = true) => {
if (isDevelopment()) {
return defaultValue
}
return df.isFeatureEnabled(featureKey)
}
Staging Workflow
// Staging workflow
const stagingWorkflow = {
steps: [
'Deploy feature to staging',
'Enable flag with internal targeting',
'Test with staging data',
'Validate performance',
'Gather feedback',
'Prepare for production',
],
}
// Staging validation
const validateStaging = async () => {
const features = await df.getAllFeatures()
for (const feature of features) {
if (feature.enabled) {
console.log(`Testing feature: ${feature.key}`)
// Run automated tests
await runFeatureTests(feature.key)
}
}
}
Production Workflow
// Production deployment workflow
const productionWorkflow = {
steps: [
'Deploy code to production',
'Enable flag with 0% rollout',
'Gradually increase rollout percentage',
'Monitor metrics and performance',
'Full rollout if successful',
'Clean up old flags',
],
}
// Gradual rollout function
const gradualRollout = async (featureKey, targetPercentage) => {
const currentPercentage = await getCurrentRolloutPercentage(featureKey)
if (currentPercentage < targetPercentage) {
const newPercentage = Math.min(currentPercentage + 10, targetPercentage)
await updateRolloutPercentage(featureKey, newPercentage)
console.log(`Rolled out ${featureKey} to ${newPercentage}%`)
// Wait and monitor
await wait(300000) // 5 minutes
await checkMetrics(featureKey)
}
}
Environment-Specific Targeting
Development Targeting
// Development targeting rules
const devTargeting = {
rules: [
{
attribute: 'user.email',
operator: 'ends_with',
value: '@company.com',
},
],
// Always enable for development
fallback: true,
}
Staging Targeting
// Staging targeting rules
const stagingTargeting = {
rules: [
{
attribute: 'user.email',
operator: 'ends_with',
value: '@company.com',
},
{
attribute: 'user.tags',
operator: 'contains',
value: 'qa-tester',
},
],
percentage: 50, // Test with 50% of eligible users
}
Production Targeting
// Production targeting rules
const productionTargeting = {
rules: [
{
attribute: 'user.plan',
operator: 'equals',
value: 'premium',
},
{
attribute: 'user.country',
operator: 'in',
value: ['US', 'CA', 'UK'],
},
],
percentage: 5, // Start with 5% rollout
sticky: true, // Ensure consistent experience
}
Environment Variables
Configuration Management
// Environment-specific configuration
const config = {
development: {
apiUrl: 'http://localhost:3000',
logLevel: 'debug',
cacheTimeout: 0,
},
staging: {
apiUrl: 'https://staging-api.example.com',
logLevel: 'info',
cacheTimeout: 30000,
},
production: {
apiUrl: 'https://api.example.com',
logLevel: 'error',
cacheTimeout: 300000,
},
}
const currentConfig = config[process.env.NODE_ENV] || config.development
Feature Flag Environment Variables
// Environment-specific feature flags
const envFlags = {
development: {
'debug-mode': true,
'mock-data': true,
'performance-monitoring': false,
},
staging: {
'debug-mode': true,
'mock-data': false,
'performance-monitoring': true,
},
production: {
'debug-mode': false,
'mock-data': false,
'performance-monitoring': true,
},
}
Best Practices
Environment Isolation
// Ensure environment isolation
const ensureEnvironmentIsolation = () => {
const currentEnv = process.env.NODE_ENV
if (currentEnv === 'production') {
// Never enable debug features in production
if (process.env.DEBUG_MODE === 'true') {
throw new Error('Debug mode cannot be enabled in production')
}
}
}
Environment Validation
// Validate environment configuration
const validateEnvironment = async () => {
const features = await df.getAllFeatures()
for (const feature of features) {
// Check for dangerous configurations
if (feature.enabled && feature.key.includes('debug')) {
console.warn(`Debug feature ${feature.key} is enabled`)
}
// Validate targeting rules
if (feature.targeting && feature.targeting.percentage > 100) {
throw new Error(`Invalid percentage for feature ${feature.key}`)
}
}
}
Environment Documentation
// Document environment configurations
const environmentDocs = {
development: {
purpose: 'Local development and testing',
features: 'All features enabled for internal users',
data: 'Mock data or development database',
access: 'Internal team only',
},
staging: {
purpose: 'Pre-production testing',
features: 'Features enabled for QA and beta testing',
data: 'Production-like data',
access: 'Internal team and beta users',
},
production: {
purpose: 'Live production environment',
features: 'Conservative feature rollouts',
data: 'Real user data',
access: 'All users',
},
}
Monitoring and Analytics
Environment-Specific Metrics
// Track metrics per environment
const trackEnvironmentMetrics = (featureKey, userId, enabled) => {
df.track('feature-evaluation', {
featureKey,
userId,
enabled,
environment: process.env.NODE_ENV,
timestamp: Date.now(),
})
}
Environment Health Checks
// Environment health monitoring
const checkEnvironmentHealth = async () => {
const health = {
environment: process.env.NODE_ENV,
timestamp: Date.now(),
features: await df.getAllFeatures(),
sdkStatus: df.getStatus(),
}
// Send health data
await sendHealthData(health)
return health
}
Next Steps
- Analytics & Metrics - Monitor environment performance
- Best Practices - Environment management guidelines
- Client-Side SDKs - Environment-aware web integration
- Server-Side SDKs - Backend environment management
Last updated on