Writing flag code
How to put a feature behind a flag so it's safe to ship, simple to roll out and quick to remove. These rules apply on every platform. AI agents connected through the MCP server get this page along with the SDK docs, so they follow it too.
Default to today's behavior
Every check passes a default. Make it the value that keeps the app as it is
now, usually false:
if (flags.isEnabled("new-checkout", false)) {
showNewCheckout();
} else {
showCheckout();
}The default is used until flags have loaded and when the flag doesn't exist, so the app behaves exactly as before in both cases.
Branch once, at the top
Check the flag at the highest point where the old and new behavior part ways, such as a route, a component or one function, and branch there. One check is easy to find and easy to remove. The same check repeated across many files is neither.
Leave the old path as it is
Add the new code beside the old code. While the flag is rolling out, both run in production for different people, so the old path must keep working unchanged. Code that both paths share has to work for both.
Check when you need the answer
Read the flag at the moment you use it, for the current user: per request on a server, per render in a UI. Don't keep the result in a module-level variable, a cache or your database. Rollouts change while the app is running, and each user gets their own answer.
Enforce on the server
A flag checked in the browser or a mobile app decides what people see. Anything about access, pricing or data must also be checked on your server, with a server SDK. Client keys are public, and people can read their own flag values.
Keep data changes working both ways
A flag can be turned up or down at any time. Make database and API changes that work with the flag on and off: add new columns and fields first, and remove old ones only after the flag is gone.
One flag for one feature
Create a new flag for each feature, with a key that names it, like
new-checkout. Don't reuse an old key for something new, and avoid making one
flag depend on another.
Test both paths
Write tests for the flag on and for the flag off. Pass the flag's value into the code under test, or stub the check, so a test doesn't depend on the flag's current setting.
Remove the flag when the rollout is done
When the feature has been on for everyone for a while:
- Delete the check and the old path from the code, and ship that.
- Then delete the flag in the dashboard.
In that order, the deployed code never checks a flag that no longer exists.