To use Flagship in a Cloudflare Worker, add a Flagship binding to your Wrangler configuration file. The binding gives your Worker access to env.FLAGS, which provides methods to evaluate feature flags.
Add the flagship block to your Wrangler configuration file with a binding name and your app ID.
{
"flagship": [
{
"binding": "FLAGS",
"app_id": "<APP_ID>",
},
],
}[[flagship]]
binding = "FLAGS"
app_id = "<APP_ID>"Replace <APP_ID> with the app ID from your Flagship app. If you have not created an app yet, refer to the Get started guide. The binding field sets the name you use to access Flagship in your Worker code (for example, env.FLAGS).
A single Worker can bind to multiple Flagship apps. Use the array form to define more than one binding:
{
"flagship": [
{
"binding": "FLAGS",
"app_id": "<APP_ID_1>",
},
{
"binding": "EXPERIMENT_FLAGS",
"app_id": "<APP_ID_2>",
},
],
}[[flagship]]
binding = "FLAGS"
app_id = "<APP_ID_1>"
[[flagship]]
binding = "EXPERIMENT_FLAGS"
app_id = "<APP_ID_2>"Each binding is available as a separate property on the env object (for example, env.FLAGS and env.EXPERIMENT_FLAGS).
After adding the binding, run npx wrangler types to generate TypeScript types. This creates the Env interface with each binding typed as Flagship.
interface Env {
FLAGS: Flagship;
EXPERIMENT_FLAGS: Flagship;
}Call evaluation methods on env.FLAGS to resolve flag values at runtime. Each method accepts a flag key, a default value, and an optional evaluation context.
export default {
async fetch(request, env) {
const isEnabled = await env.FLAGS.getBooleanValue("my-feature", false, {
userId: "user-42",
});
return new Response(isEnabled ? "Feature is on" : "Feature is off");
},
};export default {
async fetch(request: Request, env: Env): Promise<Response> {
const isEnabled = await env.FLAGS.getBooleanValue("my-feature", false, {
userId: "user-42",
});
return new Response(isEnabled ? "Feature is on" : "Feature is off");
},
};Refer to the binding API reference for the full list of methods.
During local development, Flagship bindings use a local flag store by default. This applies to wrangler dev, the Cloudflare Vite plugin, the Vitest integration, and cf dev. The store starts empty, so evaluations return the default value you pass at the call site until you add flags.
This is the default behavior in Wrangler v4.135.0 and later, and in @cloudflare/vite-plugin v1.56.0 and later.
To copy flags from your remote app into the local store:
npx wrangler flagship flags pull <APP_ID>pull also seeds the account tag used for percentage rollout bucketing, so local buckets match the remote app. Flags that exist only in the local store are left untouched.
Flags are not pulled automatically, so wrangler dev works offline and never overwrites flags you changed locally.
pull writes to the default local store in .wrangler/state. If your dev server keeps its data in a different directory, pass --persist-to <DIRECTORY> so that pull writes to the same place. For example, the Cloudflare Vite plugin 2.0 beta keeps its data in .cloudflare/state:
npx wrangler flagship flags pull <APP_ID> --persist-to .cloudflare/stateTo create or change flags without affecting the remote app, pass --local to the flag commands:
npx wrangler flagship flags create <APP_ID> new-checkout --local
npx wrangler flagship flags list <APP_ID> --localFlag commands still default to the remote app. You cannot pass --local and --remote together.
You can also inspect and edit the local store in Local Explorer. Flagship apps appear in Local Explorer in Wrangler v4.148.0 and later, and in @cloudflare/vite-plugin v1.63.0 and later.
To evaluate against the remote app during local development, set remote to true on the binding:
{
"flagship": [
{
"binding": "FLAGS",
"app_id": "<APP_ID>",
"remote": true,
},
],
}[[flagship]]
binding = "FLAGS"
app_id = "<APP_ID>"
remote = truecf dev uses the local flag store, the same as wrangler dev.
To manage local flags with cf, add --local to a supported cf flagship command. No dev server needs to be running, and the app does not need to be bound to a Worker.
cf flagship apps flags list --app-id <APP_ID> --local
cf flagship apps flags get <FLAG_KEY> --app-id <APP_ID> --localThese commands support --local:
cf flagship apps listcf flagship apps flags list,get,create,update,patch,delete, andevaluatecf flagship apps evaluate get
Other cf flagship commands, such as cf flagship apps get, cf flagship apps definitions get, and cf flagship apps flags changelog, fail with This command has no local equivalent. Run them without --local to use the remote app.
By default, cf keeps local data in its own directory, which wrangler dev and the Cloudflare Vite plugin do not read. To work on the same flags as your dev server, pass its data directory. This is .wrangler/state for wrangler dev and the Cloudflare Vite plugin 1.x, and .cloudflare/state for the Vite plugin 2.0 beta:
cf flagship apps flags list --app-id <APP_ID> --local --persist-to .wrangler/statecf cannot copy flags from your remote app. Use npx wrangler flagship flags pull <APP_ID> instead, with the same --persist-to value if you set one.