The problem with env vars for feature flags
It is common to start using environment variables as flags:
// ❌ Env vars approach
if (process.env.ENABLE_NEW_CHECKOUT === 'true') {
// new checkout
}This works initially, but brings problems:
- Mandatory redeploy for every feature change
- No history of who changed what and when
- No gradual rollout — it is all or nothing
- No reactivity — the code does not update without restarting
Migration strategy
1. Install the SDK
npm install @canarygate/sdk/js2. Create the flags in the dashboard
For each process.env.ENABLE_* you use as a toggle, create an equivalent Boolean flag in CanaryGate with the same current state.
3. Migrate one by one (no big bang)
Create a wrapper that reads from both sources during the transition:
import { CanaryGate } from '@canarygate/sdk/js/server'
const client = new CanaryGate(process.env.CANARYGATE_KEY!)
await client.init()
function isFeatureEnabled(key: string, envFallback?: string): boolean {
// Try CanaryGate first
const flag = client.getFlag(key)
if (flag !== undefined) return flag.enabled
// Fallback to env var during the transition
if (envFallback) return process.env[envFallback] === 'true'
return false
}4. Replace progressively
Before:
if (process.env.ENABLE_NEW_CHECKOUT === 'true') {After (transition phase):
if (isFeatureEnabled('new-checkout', 'ENABLE_NEW_CHECKOUT')) {After (fully migrated):
if (client.getFlag('new-checkout')?.enabled ?? false) {5. Remove the env vars
Once all flags are in CanaryGate and the wrapper is no longer needed, remove the env vars from .env and CI/CD secrets.
Equivalence table
| Env var pattern | CanaryGate equivalent |
|---|---|
ENABLE_X=true | Boolean flag, enabled = true |
ENABLE_X=false | Boolean flag, enabled = false |
FEATURE_X_ROLLOUT=25 | Rollout flag, percentage = 25 |
Advantages after migration
- Change features without redeploying — ideal for hotfixes and kill switches
- Full history of who activated what and when
- Native gradual rollout for risky features
- Real-time SSE — the SDK updates without polling or restart
Last updated on