Feature Flags
Phase 1 — Environment-Based
No external flag service needed for Phase 1. Flags are environment variables read at startup via medusa-config.ts.
// medusa-config.ts
export const featureFlags = {
gelatoIntegration: process.env.FEATURE_GELATO === "true",
publicRegistration: process.env.FEATURE_PUBLIC_REGISTRATION === "true",
loyaltyRewards: process.env.FEATURE_LOYALTY === "true",
googleOAuth: process.env.FEATURE_GOOGLE_OAUTH === "true",
}Naming Convention
| Pattern | Example | Notes |
|---|---|---|
FEATURE_{DOMAIN}_{CAPABILITY} | FEATURE_GELATO_INTEGRATION | Backend env var |
NEXT_PUBLIC_FEATURE_{X} | NEXT_PUBLIC_FEATURE_LOYALTY_UI | Frontend only |
| Flag default | false | All flags off unless explicitly enabled |
Guard Placement Rule
Feature guards belong in API route middleware or workflow steps — never scattered across service methods. One guard, at the entry point.
// src/api/store/gelato/route.ts
import { featureFlags } from "../../../medusa-config"
export const POST = async (req, res) => {
if (!featureFlags.gelatoIntegration) {
return res.status(404).json({ message: "Not found" })
}
// ... handler
}Phase 2+ — Flagsmith
When the team grows beyond 1–2 engineers or A/B testing is needed, migrate to Flagsmith (generous free tier, self-hostable). The interface stays the same — swap the env-var lookup for a Flagsmith SDK call in a single flags.ts file.