wrangler

CLI for deploying and managing Cloudflare Workers, KV, R2, D1, Vectorize, Hyperdrive, AI, Containers, Queues, Workflows, and Pipelines. Covers 10+ resource types with dedicated commands for creation, configuration, and lifecycle management across Workers, storage, databases, and compute services Supports local development with wrangler dev using local storage simulation or remote bindings for real resources; includes TypeScript type generation via wrangler types Configuration via wrangler.jsonc with support for environment-specific overrides, secrets management, cron triggers, and Durable Objects bindings Provides deployment workflows including dry-run validation, versioning, rollback, and secret management; tail command for live log streaming

INSTALLATION
npx skills add https://github.com/cloudflare/skills --skill wrangler
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

$2a

wrangler --version  # Requires v4.x+

If Wrangler is not installed, you should install it by running:

npm install -D wrangler@latest

Wherever possible, you should use Wrangler instead of manually constructing API requests.

Key Guidelines

  • **Use wrangler.jsonc**: Prefer JSON config over TOML. Newer features are JSON-only.
  • Generate types after config changes: Run wrangler types to update TypeScript bindings.
  • Local dev defaults to local storage: Bindings use local simulation unless remote: true.
  • Profile Worker startup: Run wrangler check startup to measure startup time and detect scripts that exceed the startup time limit.
  • Use environments for staging/prod: Define env.staging and env.production in config.

Quick Start: New Worker

# Initialize new project

npx wrangler init my-worker

# Or with a framework

npx create-cloudflare@latest my-app

Quick Reference: Core Commands

Task

Command

Start local dev server

wrangler dev

Deploy to Cloudflare

wrangler deploy

Deploy dry run

wrangler deploy --dry-run

Generate TypeScript types

wrangler types

Profile Worker startup time

wrangler check startup

View live logs

wrangler tail

Delete Worker

wrangler delete

Auth status

wrangler whoami

Configuration (wrangler.jsonc)

Minimal Config

{

  "$schema": "./node_modules/wrangler/config-schema.json",

  "name": "my-worker",

  "main": "src/index.ts",

  "compatibility_date": "2026-01-01"

}

Full Config with Bindings

{

  "$schema": "./node_modules/wrangler/config-schema.json",

  "name": "my-worker",

  "main": "src/index.ts",

  "compatibility_date": "2026-01-01",

  "compatibility_flags": ["nodejs_compat"],

  // Environment variables

  "vars": {

    "ENVIRONMENT": "production"

  },

  // KV Namespace

  "kv_namespaces": [

    { "binding": "KV", "id": "<KV_NAMESPACE_ID>" }

  ],

  // R2 Bucket

  "r2_buckets": [

    { "binding": "BUCKET", "bucket_name": "my-bucket" }

  ],

  // D1 Database

  "d1_databases": [

    { "binding": "DB", "database_name": "my-db", "database_id": "<DB_ID>" }

  ],

  // Workers AI (always remote)

  "ai": { "binding": "AI" },

  // Vectorize

  "vectorize": [

    { "binding": "VECTOR_INDEX", "index_name": "my-index" }

  ],

  // Hyperdrive

  "hyperdrive": [

    { "binding": "HYPERDRIVE", "id": "<HYPERDRIVE_ID>" }

  ],

  // Durable Objects

  "durable_objects": {

    "bindings": [

      { "name": "COUNTER", "class_name": "Counter" }

    ]

  },

  // Cron triggers

  "triggers": {

    "crons": ["0 * * * *"]

  },

  // Environments

  "env": {

    "staging": {

      "name": "my-worker-staging",

      "vars": { "ENVIRONMENT": "staging" }

    }

  }

}

Generate Types from Config

# Generate worker-configuration.d.ts

wrangler types

# Custom output path

wrangler types ./src/env.d.ts

# Check types are up to date (CI)

wrangler types --check

Local Development

Start Dev Server

# Local mode (default) - uses local storage simulation

wrangler dev

# With specific environment

wrangler dev --env staging

# Force local-only (disable remote bindings)

wrangler dev --local

# Remote mode - runs on Cloudflare edge (legacy)

wrangler dev --remote

# Custom port

wrangler dev --port 8787

# Live reload for HTML changes

wrangler dev --live-reload

# Test scheduled/cron handlers

wrangler dev --test-scheduled

# Then visit: http://localhost:8787/__scheduled

Remote Bindings for Local Dev

Use remote: true in binding config to connect to real resources while running locally:

{

  "r2_buckets": [

    { "binding": "BUCKET", "bucket_name": "my-bucket", "remote": true }

  ],

  "ai": { "binding": "AI", "remote": true },

  "vectorize": [

    { "binding": "INDEX", "index_name": "my-index", "remote": true }

  ]

}

Recommended remote bindings: AI (required), Vectorize, Browser Rendering, mTLS, Images.

Local Secrets

Create .dev.vars for local development secrets:

API_KEY=local-dev-key

DATABASE_URL=postgres://localhost:5432/dev

Deployment

Deploy Worker

# Deploy to production

wrangler deploy

# Deploy specific environment

wrangler deploy --env staging

# Dry run (validate without deploying)

wrangler deploy --dry-run

# Keep dashboard-set variables

wrangler deploy --keep-vars

# Minify code

wrangler deploy --minify

Manage Secrets

Security: Never pass secret values as command arguments or pipe them via echo.

Use the interactive prompt (preferred), pipe from a file, or use secret bulk.

Never output, log, or hardcode secret values in commands.

# Set secret — interactive prompt (preferred, wrangler will ask for the value securely)

wrangler secret put API_KEY

# Set secret from a file (useful for PEM keys, CI environments)

wrangler secret put PRIVATE_KEY < path/to/private-key.pem

# List secrets

wrangler secret list

# Delete secret

wrangler secret delete API_KEY

# Bulk secrets from JSON file (do not commit this file to version control)

wrangler secret bulk secrets.json

Versions and Rollback

# List recent versions

wrangler versions list

# View specific version

wrangler versions view <VERSION_ID>

# Rollback to previous version

wrangler rollback

# Rollback to specific version

wrangler rollback <VERSION_ID>

KV (Key-Value Store)

Manage Namespaces

# Create namespace

wrangler kv namespace create MY_KV

# List namespaces

wrangler kv namespace list

# Delete namespace

wrangler kv namespace delete --namespace-id <ID>

Manage Keys

# Put value

wrangler kv key put --namespace-id <ID> "key" "value"

# Put with expiration (seconds)

wrangler kv key put --namespace-id <ID> "key" "value" --expiration-ttl 3600

# Get value

wrangler kv key get --namespace-id <ID> "key"

# List keys

wrangler kv key list --namespace-id <ID>

# Delete key

wrangler kv key delete --namespace-id <ID> "key"

# Bulk put from JSON

wrangler kv bulk put --namespace-id <ID> data.json

Config Binding

{

  "kv_namespaces": [

    { "binding": "CACHE", "id": "<NAMESPACE_ID>" }

  ]

}

R2 (Object Storage)

Manage Buckets

# Create bucket

wrangler r2 bucket create my-bucket

# Create with location hint

wrangler r2 bucket create my-bucket --location wnam

# List buckets

wrangler r2 bucket list

# Get bucket info

wrangler r2 bucket info my-bucket

# Delete bucket

wrangler r2 bucket delete my-bucket

Manage Objects

# Upload object

wrangler r2 object put my-bucket/path/file.txt --file ./local-file.txt

# Download object

wrangler r2 object get my-bucket/path/file.txt

# Delete object

wrangler r2 object delete my-bucket/path/file.txt

Config Binding

{

  "r2_buckets": [

    { "binding": "ASSETS", "bucket_name": "my-bucket" }

  ]

}

D1 (SQL Database)

Manage Databases

# Create database

wrangler d1 create my-database

# Create with location

wrangler d1 create my-database --location wnam

# List databases

wrangler d1 list

# Get database info

wrangler d1 info my-database

# Delete database

wrangler d1 delete my-database

Execute SQL

# Execute SQL command (remote)

wrangler d1 execute my-database --remote --command "SELECT * FROM users"

# Execute SQL file (remote)

wrangler d1 execute my-database --remote --file ./schema.sql

# Execute locally

wrangler d1 execute my-database --local --command "SELECT * FROM users"

Migrations

# Create migration

wrangler d1 migrations create my-database create_users_table

# List pending migrations

wrangler d1 migrations list my-database --local

# Apply migrations locally

wrangler d1 migrations apply my-database --local

# Apply migrations to remote

wrangler d1 migrations apply my-database --remote

Export/Backup

# Export schema and data

wrangler d1 export my-database --remote --output backup.sql

# Export schema only

wrangler d1 export my-database --remote --output schema.sql --no-data

Config Binding

{

  "d1_databases": [

    {

      "binding": "DB",

      "database_name": "my-database",

      "database_id": "<DATABASE_ID>",

      "migrations_dir": "./migrations"

    }

  ]

}

Vectorize (Vector Database)

Manage Indexes

# Create index with dimensions

wrangler vectorize create my-index --dimensions 768 --metric cosine

# Create with preset (auto-configures dimensions/metric)

wrangler vectorize create my-index --preset @cf/baai/bge-base-en-v1.5

# List indexes

wrangler vectorize list

# Get index info

wrangler vectorize get my-index

# Delete index

wrangler vectorize delete my-index

Manage Vectors

# Insert vectors from NDJSON file

wrangler vectorize insert my-index --file vectors.ndjson

# Query vectors

wrangler vectorize query my-index --vector "[0.1, 0.2, ...]" --top-k 10

Config Binding

{

  "vectorize": [

    { "binding": "SEARCH_INDEX", "index_name": "my-index" }

  ]

}

Hyperdrive (Database Accelerator)

Manage Configs

# Create config

wrangler hyperdrive create my-hyperdrive \

  --origin-host db.example.com \

  --origin-port 5432 \

  --database my-database \

  --origin-user db-user \

  --origin-password "$DB_PASSWORD"

# Or using a connection string from an environment variable

wrangler hyperdrive create my-hyperdrive \

  --connection-string "$HYPERDRIVE_CONNECTION_STRING"

# List configs

wrangler hyperdrive list

# Get config details

wrangler hyperdrive get <HYPERDRIVE_ID>

# Update config

wrangler hyperdrive update <HYPERDRIVE_ID> \

  --origin-password "$DB_PASSWORD"

# Delete config

wrangler hyperdrive delete <HYPERDRIVE_ID>

Config Binding

{

  "compatibility_flags": ["nodejs_compat"],

  "hyperdrive": [

    { "binding": "HYPERDRIVE", "id": "<HYPERDRIVE_ID>" }

  ]

}

Workers AI

List Models

# List available models

wrangler ai models

# List finetunes

wrangler ai finetune list

Config Binding

{

  "ai": { "binding": "AI" }

}

Note: Workers AI always runs remotely and incurs usage charges even in local dev.

Queues

Manage Queues

# Create queue

wrangler queues create my-queue

# List queues

wrangler queues list

# Delete queue

wrangler queues delete my-queue

# Add consumer to queue

wrangler queues consumer add my-queue my-worker

# Remove consumer

wrangler queues consumer remove my-queue my-worker

Config Binding

{

  "queues": {

    "producers": [

      { "binding": "MY_QUEUE", "queue": "my-queue" }

    ],

    "consumers": [

      {

        "queue": "my-queue",

        "max_batch_size": 10,

        "max_batch_timeout": 30

      }

    ]

  }

}

Containers

Build and Push Images

# Build container image

wrangler containers build -t my-app:latest .

# Build and push in one command

wrangler containers build -t my-app:latest . --push

# Push existing image to Cloudflare registry

wrangler containers push my-app:latest

Manage Containers

# List containers

wrangler containers list

# Get container info

wrangler containers info <CONTAINER_ID>

# Delete container

wrangler containers delete <CONTAINER_ID>

Manage Images

# List images in registry

wrangler containers images list

# Delete image

wrangler containers images delete my-app:latest

Manage External Registries

Security: Never hardcode registry credentials in commands. Use environment variables.

# List configured registries

wrangler containers registries list

# Configure external registry (e.g., ECR)

wrangler containers registries configure <DOMAIN> \

  --aws-access-key-id "$AWS_ACCESS_KEY_ID"

# Configure DockerHub

wrangler containers registries configure <DOMAIN> \

  --dockerhub-username "$DOCKERHUB_USERNAME"

# Delete registry configuration

wrangler containers registries delete <DOMAIN>

Workflows

Manage Workflows

# List workflows

wrangler workflows list

# Describe workflow

wrangler workflows describe my-workflow

# Trigger workflow instance

wrangler workflows trigger my-workflow

# Trigger with parameters

wrangler workflows trigger my-workflow --params '{"key": "value"}'

# Delete workflow

wrangler workflows delete my-workflow

Manage Workflow Instances

# List instances

wrangler workflows instances list my-workflow

# Describe instance

wrangler workflows instances describe my-workflow <INSTANCE_ID>

# Terminate instance

wrangler workflows instances terminate my-workflow <INSTANCE_ID>

Config Binding

{

  "workflows": [

    {

      "binding": "MY_WORKFLOW",

      "name": "my-workflow",

      "class_name": "MyWorkflow"

    }

  ]

}

Pipelines

Manage Pipelines

# Create pipeline

wrangler pipelines create my-pipeline --r2 my-bucket

# List pipelines

wrangler pipelines list

# Show pipeline details

wrangler pipelines show my-pipeline

# Update pipeline

wrangler pipelines update my-pipeline --batch-max-mb 100

# Delete pipeline

wrangler pipelines delete my-pipeline

Config Binding

{

  "pipelines": [

    { "binding": "MY_PIPELINE", "pipeline": "my-pipeline" }

  ]

}

Secrets Store

Manage Stores

# Create store

wrangler secrets-store store create my-store

# List stores

wrangler secrets-store store list

# Delete store

wrangler secrets-store store delete <STORE_ID>

Manage Secrets in Store

# Add secret to store

wrangler secrets-store secret put <STORE_ID> my-secret

# List secrets in store

wrangler secrets-store secret list <STORE_ID>

# Get secret

wrangler secrets-store secret get <STORE_ID> my-secret

# Delete secret from store

wrangler secrets-store secret delete <STORE_ID> my-secret

Config Binding

{

  "secrets_store_secrets": [

    {

      "binding": "MY_SECRET",

      "store_id": "<STORE_ID>",

      "secret_name": "my-secret"

    }

  ]

}

Pages (Frontend Deployment)

# Create Pages project

wrangler pages project create my-site

# Deploy directory to Pages

wrangler pages deploy ./dist

# Deploy with specific branch

wrangler pages deploy ./dist --branch main

# List deployments

wrangler pages deployment list --project-name my-site

Observability

Tail Logs

# Stream live logs

wrangler tail

# Tail specific Worker

wrangler tail my-worker

# Filter by status

wrangler tail --status error

# Filter by search term

wrangler tail --search "error"

# JSON output

wrangler tail --format json

Config Logging

{

  "observability": {

    "enabled": true,

    "head_sampling_rate": 1

  }

}

Testing

Local Testing with Vitest

npm install -D @cloudflare/vitest-pool-workers vitest

vitest.config.ts:

import { defineWorkersConfig } from "@cloudflare/vitest-pool-workers/config";

export default defineWorkersConfig({

  test: {

    poolOptions: {

      workers: {

        wrangler: { configPath: "./wrangler.jsonc" },

      },

    },

  },

});

Test Scheduled Events

# Enable in dev

wrangler dev --test-scheduled

# Trigger via HTTP

curl http://localhost:8787/__scheduled

Troubleshooting

Common Issues

Issue

Solution

command not found: wrangler

Install: npm install -D wrangler

Auth errors

Run wrangler login

Startup time limit exceeded

Run wrangler check startup to profile startup and generate CPU profiles

Type errors after config change

Run wrangler types

Local storage not persisting

Check .wrangler/state directory

Binding undefined in Worker

Verify binding name matches config exactly

Debug Commands

# Check auth status

wrangler whoami

# Profile Worker startup time

wrangler check startup

# View config schema

wrangler docs configuration

Best Practices

  • **Version control wrangler.jsonc**: Treat as source of truth for Worker config.
  • Use automatic provisioning: Omit resource IDs for auto-creation on deploy.
  • **Run wrangler types in CI**: Add to build step to catch binding mismatches.
  • Use environments: Separate staging/production with env.staging, env.production.
  • **Set compatibility_date**: Update quarterly to get new runtime features.
  • **Use .dev.vars for local secrets**: Never commit secrets to config.
  • Test locally first: wrangler dev with local bindings before deploying.
  • **Use --dry-run before major deploys**: Validate changes without deployment.
  • Never embed secrets in commands: Use interactive prompts (wrangler secret put), file-based input (wrangler secret bulk), or secure CI environment variables. Never echo, log, or pass secret values as CLI arguments.
BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card