Feature Flags
Flags decouple deployment from release — ship safely, release when ready
Main branch should always be production-ready. Feature flags make that possible by decoupling deployment from release.
The Branch Problem
A feature takes three days to build. It can't be deployed half-finished, so it sits in a branch. Meanwhile, main keeps moving. Merge conflicts pile up. By the time it's ready, integration is a slog. The alternative — deploying broken functionality — is worse. Both options are bad. Feature flags are the way out.
How They Work
The developer deploys the code behind a flag that's disabled in production. The feature exists in the codebase but users can't see it. Development continues, testing happens against real production infrastructure, then the flag gets flipped when it's ready. The feature goes live instantly, no deployment needed.
Why It Matters
No long-lived branches means no integration hell. The developer works on main, everything stays compatible. Testing happens in the actual production environment — staging never fully matches production. The database is different, third-party APIs behave differently, network conditions vary. Testing behind a flag catches real issues before real users hit them.
Implementation
Start simple. A boolean check is enough:
if (featureFlags.newCheckout) {
return <NewCheckout />;
}
From there it can get more precise. Environment-based flags are enabled in staging and off in production. User-based flags target admins or internal testers. Percentage-based flags roll out to 10% of users before going broad. Dedicated feature flag services handle the complexity if needed. Don't over-engineer it before there's a reason to.
What This Prevents
The "big bang" deployment. Two weeks of work shipped all at once. Something breaks. Nobody knows which change caused it. Rolling back means losing everything. With feature flags, each change is isolated. Problems are obvious. Rollback is surgical — flip a flag, not revert a month of commits.