DEV Community

Young Gao
Young Gao

Posted on

Feature Flags Without a Third-Party Service

Feature Flags Without a Third-Party Service

You do not need LaunchDarkly to ship features safely. A simple flag system backed by a database or config file gets you 90% of the way.

Basic Flag Store

interface FeatureFlag {
  name: string;
  enabled: boolean;
  rolloutPercent: number; // 0-100
Enter fullscreen mode Exit fullscreen mode

allowedUsers?: string[]; // whitelist for beta testers
}

class FeatureFlagService {
private flags = new Map();

async load(): Promise {
const rows = await db.query("SELECT * FROM feature_flags");
rows.forEach((r) => this.flags.set(r.name, r));
}

isEnabled(name: string, userId?: string): boolean {
const flag = this.flags.get(name);
if (!flag || !flag.enabled) return false;
if (flag.allowedUsers?.includes(userId!)) return true;
const hash = simpleHash(${name}-${userId}) % 100;
return hash < flag.rolloutPercent;
}
}


## Usage in Routes

Enter fullscreen mode Exit fullscreen mode


typescript
app.get("/dashboard", async (req, res) => {
if (features.isEnabled("new-dashboard", req.user.id)) {
return res.render("dashboard-v2");
}
res.render("dashboard");
});




## Gradual Rollout Strategy

1. Enable for internal users (`allowedUsers` list)
2. Roll out to 10% of users
3. Monitor error rates and performance
4. Increase to 50%, then 100%
5. Remove the flag and old code path

## Cleanup Matters

Dead flags are tech debt. Set a rule: every flag gets a cleanup date. If a flag has been at 100% for 30 days, remove it and the old code path.

***

*Part of my Production Backend Patterns series. Follow for more practical backend engineering.*
Enter fullscreen mode Exit fullscreen mode

Top comments (0)