Skip to main content

Feature Flags

Use Replane to manage feature flags across your applications without deploying code.

Basic Feature Flags

Create a config named feature-flags with simple boolean values:

{
"new-onboarding": true,
"dark-mode": false,
"billing-v2": false,
"advanced-search": true
}

In your application:

import { createReplaneClient } from 'replane-sdk';

const client = createReplaneClient({
apiKey: process.env.REPLANE_API_KEY,
baseUrl: process.env.REPLANE_URL,
});

// Check a flag
const flags = await client.getConfigValue('feature-flags');

if (flags['new-onboarding']) {
// Show new onboarding flow
} else {
// Show old onboarding
}

Targeted Rollouts with Override Rules

Use override rules to target specific users or groups without managing separate values:

Config: new-feature-enabled
Base value: false
Override: VIP Users

  • Condition: Property userEmail in ["vip1@example.com", "vip2@example.com"]
  • Value: true
// Regular user - gets base value (false)
const enabled1 = await client.getConfigValue('new-feature-enabled', {
context: { userEmail: 'user@example.com' }
});

// VIP user - gets override value (true)
const enabled2 = await client.getConfigValue('new-feature-enabled', {
context: { userEmail: 'vip1@example.com' }
});

See the Override Rules Guide for advanced targeting scenarios.

Tier-Based Features

Target users by subscription tier:

Config: feature-flags
Base value:

{
"advanced-search": false,
"export-data": false
}

Override: Premium Users

  • Condition: Property tier equals "premium"
  • Value:
{
"advanced-search": true,
"export-data": true
}
const flags = await client.getConfigValue('feature-flags', {
context: { tier: user.subscription.tier }
});

if (flags['advanced-search']) {
// Show advanced search (premium users only)
}

Realtime Flag Updates

Use watchers to get instant updates when flags change:

const flags = await client.watchConfigValue('feature-flags');

// Later in your code
function isEnabled(flagName) {
return flags.get()[flagName] || false;
}

// The value updates automatically when someone changes it in the UI

JSON Schema for Safety

Prevent invalid flag configurations with a schema:

Schema for feature-flags
{
"type": "object",
"properties": {
"new-onboarding": { "type": "boolean" },
"dark-mode": { "type": "boolean" },
"billing-v2": { "type": "boolean" },
"advanced-search": { "type": "boolean" }
},
"additionalProperties": false,
"required": ["new-onboarding", "dark-mode"]
}

This ensures:

  • Only boolean values are allowed
  • Required flags are always present
  • No typos in flag names

Best Practices

Use Descriptive Names

// ❌ Bad
"flag1": true
"f2": false

// ✅ Good
"new-onboarding-flow": true
"billing-v2-enabled": false

Create separate configs for different domains:

  • feature-flags - UI features
  • api-flags - API behavior
  • experiments - A/B tests

Default to Safe Values

Always provide fallbacks:

const flags = await client
.getConfigValue('feature-flags')
.catch(() => ({
'new-feature': false, // Safe default
}));

Document Your Flags

Keep a README or wiki documenting:

  • What each flag does
  • Who owns it
  • When it was added
  • Removal plan

Migration Strategy

When removing a flag:

  1. Set it to the final value (e.g., true for fully rolled out)
  2. Remove the code that checks it
  3. Delete the flag from config (or leave it for audit history)

Next Steps