Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/content/changelog/flagship/2026-11-02-local-flag-store.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: Evaluate Flagship flags locally
description: Flagship bindings now evaluate flags against a local flag store during local development, so you can develop offline and test flag changes without touching your remote app.
products:
- flagship
date: 2026-11-02
---

[Flagship](/flagship/) bindings now evaluate flags against a local flag store during local development, instead of calling your remote app. You can develop offline and test flag changes without affecting production. This applies to [`wrangler dev`](/workers/wrangler/commands/general/#dev), the [Cloudflare Vite plugin](/workers/vite-plugin/), the [Vitest integration](/workers/testing/vitest-integration/), and [`cf dev`](/cf/projects/#start-development).

The local store starts empty, so evaluations return the default value you pass in code. Add and manage local flags in any of these ways:

- **Wrangler** — Add `--local` to `wrangler flagship flags` commands, such as `create`, `update`, and `evaluate`. To copy all flags from your remote app, run `npx wrangler flagship flags pull <APP_ID>`.
- **Local Explorer** — Create, edit, toggle, and evaluate flags in [Local Explorer](/workers/local-development/local-explorer/) while your dev server runs.
- **`cf` CLI** — Add `--local` to [`cf flagship` commands](/flagship/configuration/#use-the-cf-cli).

To keep evaluating against your remote app instead, set [`remote: true`](/flagship/configuration/#use-the-remote-app-instead) on the binding.

The local flag store requires Wrangler v4.135.0 or `@cloudflare/vite-plugin` v1.56.0 or later. Flagship in Local Explorer requires Wrangler v4.148.0 or `@cloudflare/vite-plugin` v1.63.0 or later.

Refer to [Flagship local development](/flagship/configuration/#local-development) for details.
6 changes: 5 additions & 1 deletion src/content/docs/cf/projects/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,11 @@ needs to be running. Local support covers these commands:
- `cf d1 migrations list` and `cf d1 migrations apply`
- `cf r2 objects get`, `cf r2 objects put`, `cf r2 objects list`, and
`cf r2 objects bulk-delete`
- `cf d1 list`, `cf kv namespaces list`, and `cf r2 buckets list`
- `cf flagship apps flags list`, `get`, `create`, `update`, `patch`, `delete`,
and `evaluate`
- `cf flagship apps evaluate get`
- `cf d1 list`, `cf kv namespaces list`, `cf flagship apps list`, and
`cf r2 buckets list`

`cf d1 query` has no local equivalent. Use `cf d1 raw` instead. A command
without a local equivalent fails with
Expand Down
82 changes: 81 additions & 1 deletion src/content/docs/flagship/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,84 @@ Refer to the [binding API reference](/flagship/binding/) for the full list of me

## Local development

Flagship bindings work with `wrangler dev`. Local Workers use the live Flagship app configured by `app_id`. There is no local flag store. Make sure your local Wrangler configuration points to a valid Flagship app before testing evaluations.
During local development, Flagship bindings use a local flag store by default. This applies to [`wrangler dev`](/workers/wrangler/commands/general/#dev), the [Cloudflare Vite plugin](/workers/vite-plugin/), the [Vitest integration](/workers/testing/vitest-integration/), and [`cf dev`](/cf/projects/#start-development). 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.

### Copy flags from your remote app

To copy flags from your remote app into the local store:

```sh
npx wrangler flagship flags pull <APP_ID>
```

`pull` also seeds the account tag used for [percentage rollout](/flagship/targeting/percentage-rollouts/) 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`:

```sh
npx wrangler flagship flags pull <APP_ID> --persist-to .cloudflare/state
```

### Manage the local store

To create or change flags without affecting the remote app, pass `--local` to the flag commands:

```sh
npx wrangler flagship flags create <APP_ID> new-checkout --local
npx wrangler flagship flags list <APP_ID> --local
```

Flag 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](/workers/local-development/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.

### Use the remote app instead

To evaluate against the remote app during local development, set `remote` to `true` on the binding:

<WranglerConfig>

```jsonc
{
"flagship": [
{
"binding": "FLAGS",
"app_id": "<APP_ID>",
"remote": true,
},
],
}
```

</WranglerConfig>

### Use the cf CLI

[`cf dev`](/cf/projects/#start-development) 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.

```sh
cf flagship apps flags list --app-id <APP_ID> --local
cf flagship apps flags get <FLAG_KEY> --app-id <APP_ID> --local
```

These commands support `--local`:

- `cf flagship apps list`
- `cf flagship apps flags list`, `get`, `create`, `update`, `patch`, `delete`, and `evaluate`
- `cf 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](/cf/projects/#local-resource-data), 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:

```sh
cf flagship apps flags list --app-id <APP_ID> --local --persist-to .wrangler/state
```

`cf` 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.
14 changes: 14 additions & 0 deletions src/content/docs/flagship/get-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,19 @@ export default {

The third argument to `getBooleanValue` is the [evaluation context](/flagship/concepts/#evaluation-context). Flagship uses the context attributes to match targeting rules. In this example, the `userId` attribute is passed so that percentage rollouts and user-specific targeting work correctly.

## Test locally

Copy the flag into the local store, then start a local session:

```sh
npx wrangler flagship flags pull <APP_ID>
npx wrangler dev
```

To use the [Cloudflare Vite plugin](/workers/vite-plugin/) instead, start your Vite dev server. In a [`cf`](/cf/) project, run `cf dev`, and add `--persist-to .cloudflare/state` to the `pull` command. Either way, run the Wrangler `pull` command first, because `cf` cannot pull flags.

Without `pull`, the local store is empty, so evaluations return the default value you pass in code. For other ways to manage local flags, and to use your remote app instead, refer to [Local development](/flagship/configuration/#local-development).

## Deploy and test

Deploy your Worker:
Expand Down Expand Up @@ -180,6 +193,7 @@ Refer to the [SDK documentation](/flagship/sdk/) for detailed setup instructions
## Next steps

- Manage flags from the command line with the [`wrangler flagship` commands](/flagship/reference/wrangler-commands/).
- Test against a [local flag store](/flagship/configuration/#local-development) with Wrangler, the Vite plugin, or `cf dev`.
- Learn about [targeting rules](/flagship/targeting/) to serve different values based on user attributes.
- Explore the full [binding API reference](/flagship/binding/) for all evaluation methods.
- Read about [percentage rollouts](/flagship/targeting/percentage-rollouts/) for gradual feature releases.
Expand Down
2 changes: 2 additions & 0 deletions src/content/docs/flagship/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ description: Ship features safely with Flagship, Cloudflare's feature flag servi
pcx_content_type: overview
sidebar:
order: 1
badge:
text: Beta
head:
- tag: title
content: Overview
Expand Down
25 changes: 24 additions & 1 deletion src/content/docs/flagship/reference/wrangler-commands.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Use `wrangler flagship` to manage Flagship apps and feature flags from the comma

### Authenticate Wrangler

`wrangler flagship` calls the Cloudflare API. Authenticate Wrangler before running commands:
Commands that target the remote app call the Cloudflare API. Authenticate Wrangler before running them:

```sh
wrangler login
Expand Down Expand Up @@ -51,6 +51,29 @@ This binding is only used by your Worker's runtime code (`env.FLAGS`). `wrangler

</Aside>

## Local flag store

[`wrangler dev`](/workers/wrangler/commands/general/#dev), the [Cloudflare Vite plugin](/workers/vite-plugin/), and [`cf dev`](/cf/projects/#start-development) evaluate Flagship bindings against a local flag store. The store starts empty and is not filled automatically.

Copy flags from the remote app into that store:

```sh
wrangler flagship flags pull <APP_ID>
Comment thread
akshitsinha marked this conversation as resolved.
```

`pull` requires authentication because it reads the remote app. Matching keys are overwritten. Flags that exist only locally are reported, not deleted. `pull` writes to the default local store in `.wrangler/state`; pass `--persist-to <DIRECTORY>` if your dev server keeps its data elsewhere.

`create`, `get`, `list`, `update`, `delete`, `enable`, `disable`, `set`, `rollout`, `split`, `evaluate`, and the `rules` commands accept `--local` to read and write the local store. They still default to the remote app.

```sh
wrangler flagship flags list <APP_ID> --local
wrangler flagship flags create <APP_ID> new-checkout --local
```

You cannot pass `--local` and `--remote` together. `--persist-to` requires `--local`.

For binding configuration, including `remote: true`, and for managing the local store with the `cf` CLI, refer to [Local development](/flagship/configuration/#local-development).

## Quick start

Create a boolean flag, evaluate it for a user, and disable it as a kill switch:
Expand Down
20 changes: 20 additions & 0 deletions src/content/docs/workers/local-development/local-data.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,26 @@ You may also include [other metadata](/workers/wrangler/commands/r2/#r2-object-p
args="d1 execute <DATABASE_NAME> --file=./schema.sql --local"
/>

### Flagship apps

#### [Copy flags from a remote app](/flagship/configuration/#local-development)

<PackageManagers
type="exec"
pkg="wrangler"
args="flagship flags pull <APP_ID>"
/>

#### [Create a flag in the local store](/flagship/reference/wrangler-commands/#local-flag-store)

<PackageManagers
type="exec"
pkg="wrangler"
args="flagship flags create <APP_ID> new-checkout --local"
/>

To manage the local store with the `cf` CLI instead, refer to [Flagship local development](/flagship/configuration/#use-the-cf-cli).

### Durable Objects

For Durable Objects, unlike KV, D1, and R2, there are no CLI commands to populate them with local data. To add data to Durable Objects during local development, you must write application code that creates Durable Object instances and [calls methods on them that store state](/durable-objects/best-practices/access-durable-objects-storage/). This typically involves creating development endpoints or test routes that initialize your Durable Objects with the desired data.
Expand Down
8 changes: 8 additions & 0 deletions src/content/docs/workers/wrangler/commands/flagship.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ Use `wrangler flagship` to manage [Flagship](/flagship/) apps and feature flags

`wrangler flagship` is available in Wrangler v4.107.0 and later.

:::note[`--local` option]
Most `wrangler flagship flags` commands accept `--local` to read and write the local flag store used by [`wrangler dev`](/workers/wrangler/commands/general/#dev), the [Cloudflare Vite plugin](/workers/vite-plugin/), and [`cf dev`](/cf/projects/#start-development). They still default to the remote app. Bindings with `remote: true` do not use the local store, so `--local` changes do not affect them.

`wrangler flagship flags pull <APP_ID>` copies remote flags into that store.

For more information, refer to [Flagship local development](/flagship/configuration/#local-development).
:::

## Authentication

Run `wrangler login`, or set [`CLOUDFLARE_API_TOKEN`](/workers/wrangler/system-environment-variables/) to an API token with Flagship permissions.
Expand Down
33 changes: 33 additions & 0 deletions src/content/docs/workers/wrangler/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,9 @@ Non-inheritable keys are configurable at the top-level, but cannot be inherited
- `secrets_store_secrets` <Type text="object" /> <MetaInfo text="optional" />
- A list of Secrets Store bindings that your worker should be bound to. Refer to [Secrets Store](/secrets-store/).

- `flagship` <Type text="object" /> <MetaInfo text="optional" />
- A list of Flagship apps that your Worker should be bound to. Refer to [Flagship](#flagship).

## Types of routes

There are three types of [routes](/workers/configuration/routing/): [Custom Domains](/workers/configuration/routing/custom-domains/), [routes](/workers/configuration/routing/routes/), and [`workers.dev`](/workers/configuration/routing/workers-dev/).
Expand Down Expand Up @@ -768,6 +771,36 @@ Example:

<Render file="envvar-example" product="workers" />

### Flagship

[Flagship](/flagship/) is Cloudflare's feature flag service. Bind a Flagship app to evaluate flags from your Worker.

- `binding` <Type text="string" /> <MetaInfo text="required" />
- The binding name used to refer to the Flagship app. The binding must be [a valid JavaScript variable name](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#variables).

- `app_id` <Type text="string" /> <MetaInfo text="optional" />
- The ID of the Flagship app.

- `remote` <Type text="boolean" /> <MetaInfo text="optional" />
- During local development, Flagship bindings use a [local flag store](/flagship/configuration/#local-development) by default. Set `remote` to `true` to evaluate against the remote app instead.

Example:

<WranglerConfig>

```jsonc
{
"flagship": [
{
"binding": "FLAGS",
"app_id": "<APP_ID>",
},
],
}
```

</WranglerConfig>

### Hyperdrive

[Hyperdrive](/hyperdrive/) bindings allow you to interact with and query any Postgres database from within a Worker.
Expand Down
2 changes: 2 additions & 0 deletions src/content/partials/workers/bindings_per_env.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
| **Durable Objects** | ✅ | ❌ [^1] |
| **Containers** | ✅ | ❌ |
| **Email Bindings** | ✅ | ✅ |
| **Flagship** | ✅ | ✅ |
| **Hyperdrive** | ✅ | ❌ |
| **Images** | ✅ | ✅ |
| **KV** | ✅ | ✅ |
Expand Down Expand Up @@ -48,6 +49,7 @@ Supported only in [`wrangler dev --remote`](/workers/wrangler/commands/general/#
| **Durable Objects** | ✅ |
| **Containers** | ❌ |
| **Email Bindings** | ✅ |
| **Flagship** | ✅ |
| **Hyperdrive** | ✅ |
| **Images** | ✅ |
| **KV** | ✅ |
Expand Down
Loading