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:
- Local:
wrangler login(account ID auto-resolved fromwrangler whoami) - CI:
CLOUDFLARE_API_TOKEN+CLOUDFLARE_ACCOUNT_ID
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}`); }}