Skip to Content
GuidesMigrar de Env Vars

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/js

2. 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 patternCanaryGate equivalent
ENABLE_X=trueBoolean flag, enabled = true
ENABLE_X=falseBoolean flag, enabled = false
FEATURE_X_ROLLOUT=25Rollout 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