Skip to main content

Implementing Feature Flags

This page gives three examples on how to use feature flags in TypeScript.

Example 1: Basic Feature Flag Implementation

In this example, we'll create a simple feature flag system using a dictionary to store the feature flags and a class to check their states.

interface FeatureFlags {
[key: string]: boolean;
}

class FeatureFlag {
private flags: FeatureFlags;

constructor(flags: FeatureFlags) {
this.flags = flags;
}

isEnabled(flag: string): boolean {
return this.flags[flag] || false;
}
}

// Sample usage
const flags = new FeatureFlag({
new_dashboard: true,
beta_feature: false,
});

if (flags.isEnabled('new_dashboard')) {
console.log('Showing new dashboard');
} else {
console.log('Showing old dashboard');
}

Example 2: Using Environment Variables for Feature Flags

In this example, we'll use environment variables to manage feature flags, allowing us to change feature states without modifying the codebase.

// .env file
// NEW_DASHBOARD=true
// BETA_FEATURE=false

import * as dotenv from 'dotenv';
dotenv.config();

class FeatureFlag {
isEnabled(flag: string): boolean {
return process.env[flag] === 'true';
}
}

// Sample usage
const featureFlag = new FeatureFlag();

if (featureFlag.isEnabled('NEW_DASHBOARD')) {
console.log('Showing new dashboard');
} else {
console.log('Showing old dashboard');
}

if (featureFlag.isEnabled('BETA_FEATURE')) {
console.log('Enabling beta feature');
} else {
console.log('Beta feature disabled');
}

Example 3: Advanced Feature Flags with Contextual Targeting

In this example, we'll implement a more advanced feature flag system that allows for contextual targeting based on user roles or other criteria.

interface FeatureFlags {
[key: string]: boolean;
}

class FeatureFlag {
private flags: FeatureFlags;

constructor(flags: FeatureFlags) {
this.flags = flags;
}

isEnabled(flag: string, context?: any): boolean {
if (!this.flags[flag]) return false;

// Additional context-based logic
if (context?.role && flag === 'admin_feature') {
return context.role === 'admin';
}

return true;
}
}

// Sample usage
const flags = new FeatureFlag({
new_dashboard: true,
beta_feature: false,
admin_feature: true,
});

const userContext = { role: 'admin' };
const guestContext = { role: 'guest' };

console.log('Admin user:');
console.log(flags.isEnabled('new_dashboard', userContext)); // true
console.log(flags.isEnabled('beta_feature', userContext)); // false
console.log(flags.isEnabled('admin_feature', userContext)); // true

console.log('Guest user:');
console.log(flags.isEnabled('new_dashboard', guestContext)); // true
console.log(flags.isEnabled('beta_feature', guestContext)); // false
console.log(flags.isEnabled('admin_feature', guestContext)); // false

Conclusion

These three examples demonstrate different ways to implement feature flags in TypeScript, ranging from basic to advanced. By using feature flags, you can control the availability of features dynamically, improve the flexibility of your deployments, and enhance the overall development workflow.