Remote State
By default, wrangler-deploy stores state locally in .wrangler-deploy/<stage>/state.json. This works for solo developers but breaks when multiple people or CI pipelines manage the same stage.
The problem
Section titled “The problem”| Scenario | What happens with local state |
|---|---|
| Dev A applies, Dev B deploys | B has no state, deploy fails |
| Dev applies, CI deploys | CI has no state |
| Multiple devs on same stage | Each has their own copy, they drift |
Remote KV state
Section titled “Remote KV state”Store state in a shared Cloudflare KV namespace:
export default defineConfig({ version: 1, state: { backend: "kv", namespaceId: "your-kv-namespace-id", }, // ...});-
Create a KV namespace for state:
Terminal window wrangler kv namespace create wrangler-deploy-state -
Copy the namespace ID into your config.
-
Every command now reads/writes state from KV, shared across all team members and CI.
How it works
Section titled “How it works”wd applyreads state from KV, provisions resources, writes updated state back to KVwd deployreads state from KV before deployingwd destroyreads state from KV, deletes resources, removes state from KVwd statusreads state from KVwd secretsreads/writes state from KVwd gclists all stages from KV, checks TTLs
All commands go through the StateProvider interface. Switching between local and KV is a config change, not a code change.
Authentication
Section titled “Authentication”Remote state uses the same auth as all other wrangler-deploy operations. Account resolution is documented in How it works — Authentication. In short:
- Local:
wrangler login/wrangler whoami, with optional fallback to OAuthdefault.tomlwhen no API token is set - CI:
CLOUDFLARE_API_TOKENplus an explicit account id (CLOUDFLARE_ACCOUNT_IDoverrides.wdrcaccountIdwhen both are set), or a workingwrangler whoamiwith that token. With a token set,default.tomlis not used (avoids error 10000)
Key format
Section titled “Key format”State is stored in KV with keys like wrangler-deploy/<stage-name>. You can customise the prefix:
state: { backend: "kv", namespaceId: "your-namespace-id", keyPrefix: "my-project/", // default: "wrangler-deploy/"}Local state (default)
Section titled “Local state (default)”If you omit the state config or set backend: "local", state is stored on disk:
.wrangler-deploy/ staging/ state.json pr-123/ state.jsonThis is fine for:
- Solo development
- CI that runs apply + deploy in the same step
- Ephemeral stages managed from a single machine
Migration
Section titled “Migration”To move from local to remote state:
import { LocalStateProvider, KvStateProvider } from "wrangler-deploy";
const local = new LocalStateProvider(".");const kv = new KvStateProvider(".", "your-namespace-id");
for (const stage of await local.list()) { const state = await local.read(stage); if (state) { await kv.write(stage, state); console.log(`Migrated ${stage}`); }}