{"name":"wrangler","url":"https://github.com/cloudflare/skills/tree/main/skills/wrangler","sdk":"cloudflare","key":"cloudflare/wrangler","description":"Cloudflare Workers CLI for deploying, developing, and managing Workers, KV, R2, D1, Vectorize, Hyperdrive, Workers AI, Containers, Queues, Workflows, Pipelines, and Secrets Store. Load before running wrangler commands to ensure correct syntax and best practices. Biases towards retrieval from Cloudflare docs over pre-trained knowledge.","hasContent":true,"content":"---\nname: wrangler\ndescription: Cloudflare Workers CLI for deploying, developing, and managing Workers, KV, R2, D1, Vectorize, Hyperdrive, Workers AI, Containers, Queues, Workflows, Pipelines, and Secrets Store. Load before running wrangler commands to ensure correct syntax and best practices. Biases towards retrieval from Cloudflare docs over pre-trained knowledge.\n---\n\n# Wrangler CLI\n\nYour knowledge of Wrangler CLI flags, config fields, and subcommands may be outdated. **Prefer retrieval over pre-training** for any Wrangler task.\n\n## Retrieval Sources\n\nFetch the **latest** information before writing or reviewing Wrangler commands and config. Do not rely on baked-in knowledge for CLI flags, config fields, or binding shapes.\n\n| Source | How to retrieve | Use for |\n|--------|----------------|---------|\n| Wrangler docs | `https://developers.cloudflare.com/workers/wrangler/` | CLI commands, flags, config reference |\n| Wrangler config schema | `node_modules/wrangler/config-schema.json` | Config fields, binding shapes, allowed values |\n| Cloudflare docs | Search tool or `https://developers.cloudflare.com/workers/` | API reference, compatibility dates/flags |\n\n## FIRST: Check if Wrangler is installed, and if not, install it\n\nCheck if Wrangler is installed by running:\n\n```bash\nwrangler --version  # Requires v4.x+\n```\n\nIf Wrangler is not installed, you should install it by running:\n\n```bash\nnpm install -D wrangler@latest\n```\n\nWherever possible, you should use Wrangler instead of manually constructing API requests.\n\n## Key Guidelines\n\n- **Use `wrangler.jsonc`**: Prefer JSON config over TOML. Newer features are JSON-only.\n- **Set `compatibility_date`**: Use a recent date (within 30 days). Check https://developers.cloudflare.com/workers/configuration/compatibility-dates/\n- **Generate types after config changes**: Run `wrangler types` to update TypeScript bindings.\n- **Local dev defaults to local storage**: Bindings use local simulation unless `remote: true`.\n- **Profile Worker startup**: Run `wrangler check startup` to measure startup time and detect scripts that exceed the startup time limit.\n- **Use environments for staging/prod**: Define `env.staging` and `env.production` in config.\n\n## Quick Start: New Worker\n\n```bash\n# Initialize new project\nnpx wrangler init my-worker\n\n# Or with a framework\nnpx create-cloudflare@latest my-app\n```\n\n## Quick Reference: Core Commands\n\n| Task | Command |\n|------|---------|\n| Start local dev server | `wrangler dev` |\n| Deploy to Cloudflare | `wrangler deploy` |\n| Deploy dry run | `wrangler deploy --dry-run` |\n| Generate TypeScript types | `wrangler types` |\n| Profile Worker startup time | `wrangler check startup` |\n| View live logs | `wrangler tail` |\n| Delete Worker | `wrangler delete` |\n| Auth status | `wrangler whoami` |\n\n---\n\n## Configuration (wrangler.jsonc)\n\n### Minimal Config\n\n```jsonc\n{\n  \"$schema\": \"./node_modules/wrangler/config-schema.json\",\n  \"name\": \"my-worker\",\n  \"main\": \"src/index.ts\",\n  \"compatibility_date\": \"2026-01-01\"\n}\n```\n\n### Full Config with Bindings\n\n```jsonc\n{\n  \"$schema\": \"./node_modules/wrangler/config-schema.json\",\n  \"name\": \"my-worker\",\n  \"main\": \"src/index.ts\",\n  \"compatibility_date\": \"2026-01-01\",\n  \"compatibility_flags\": [\"nodejs_compat\"],\n\n  // Environment variables\n  \"vars\": {\n    \"ENVIRONMENT\": \"production\"\n  },\n\n  // KV Namespace\n  \"kv_namespaces\": [\n    { \"binding\": \"KV\", \"id\": \"<KV_NAMESPACE_ID>\" }\n  ],\n\n  // R2 Bucket\n  \"r2_buckets\": [\n    { \"binding\": \"BUCKET\", \"bucket_name\": \"my-bucket\" }\n  ],\n\n  // D1 Database\n  \"d1_databases\": [\n    { \"binding\": \"DB\", \"database_name\": \"my-db\", \"database_id\": \"<DB_ID>\" }\n  ],\n\n  // Workers AI (always remote)\n  \"ai\": { \"binding\": \"AI\" },\n\n  // Vectorize\n  \"vectorize\": [\n    { \"binding\": \"VECTOR_INDEX\", \"index_name\": \"my-index\" }\n  ],\n\n  // Hyperdrive\n  \"hyperdrive\": [\n    { \"binding\": \"HYPERDRIVE\", \"id\": \"<HYPERDRIVE_ID>\" }\n  ],\n\n  // Durable Objects\n  \"durable_objects\": {\n    \"bindings\": [\n      { \"name\": \"COUNTER\", \"class_name\": \"Counter\" }\n    ]\n  },\n\n  // Cron triggers\n  \"triggers\": {\n    \"crons\": [\"0 * * * *\"]\n  },\n\n  // Environments\n  \"env\": {\n    \"staging\": {\n      \"name\": \"my-worker-staging\",\n      \"vars\": { \"ENVIRONMENT\": \"staging\" }\n    }\n  }\n}\n```\n\n### Generate Types from Config\n\n```bash\n# Generate worker-configuration.d.ts\nwrangler types\n\n# Custom output path\nwrangler types ./src/env.d.ts\n\n# Check types are up to date (CI)\nwrangler types --check\n```\n\n---\n\n## Local Development\n\n### Start Dev Server\n\n```bash\n# Local mode (default) - uses local storage simulation\nwrangler dev\n\n# With specific environment\nwrangler dev --env staging\n\n# Force local-only (disable remote bindings)\nwrangler dev --local\n\n# Remote mode - runs on Cloudflare edge (legacy)\nwrangler dev --remote\n\n# Custom port\nwrangler dev --port 8787\n\n# Live reload for HTML changes\nwrangler dev --live-reload\n\n# Test scheduled/cron handlers\nwrangler dev --test-scheduled\n# Then visit: http://localhost:8787/__scheduled\n```\n\n### Remote Bindings for Local Dev\n\nUse `remote: true` in binding config to connect to real resources while running locally:\n\n```jsonc\n{\n  \"r2_buckets\": [\n    { \"binding\": \"BUCKET\", \"bucket_name\": \"my-bucket\", \"remote\": true }\n  ],\n  \"ai\": { \"binding\": \"AI\", \"remote\": true },\n  \"vectorize\": [\n    { \"binding\": \"INDEX\", \"index_name\": \"my-index\", \"remote\": true }\n  ]\n}\n```\n\n**Recommended remote bindings**: AI (required), Vectorize, Browser Rendering, mTLS, Images.\n\n### Local Secrets\n\nCreate `.dev.vars` for local development secrets:\n\n```\nAPI_KEY=local-dev-key\nDATABASE_URL=postgres://localhost:5432/dev\n```\n\n---\n\n## Deployment\n\n### Deploy Worker\n\n```bash\n# Deploy to production\nwrangler deploy\n\n# Deploy specific environment\nwrangler deploy --env staging\n\n# Dry run (validate without deploying)\nwrangler deploy --dry-run\n\n# Keep dashboard-set variables\nwrangler deploy --keep-vars\n\n# Minify code\nwrangler deploy --minify\n```\n\n### Manage Secrets\n\n> **Security**: Never pass secret values as command arguments or pipe them via `echo`.\n> Use the interactive prompt (preferred), pipe from a file, or use `secret bulk`.\n> Never output, log, or hardcode secret values in commands.\n\n```bash\n# Set secret — interactive prompt (preferred, wrangler will ask for the value securely)\nwrangler secret put API_KEY\n\n# Set secret from a file (useful for PEM keys, CI environments)\nwrangler secret put PRIVATE_KEY < path/to/private-key.pem\n\n# List secrets\nwrangler secret list\n\n# Delete secret\nwrangler secret delete API_KEY\n\n# Bulk secrets from JSON file (do not commit this file to version control)\nwrangler secret bulk secrets.json\n```\n\n### Versions and Rollback\n\n```bash\n# List recent versions\nwrangler versions list\n\n# View specific version\nwrangler versions view <VERSION_ID>\n\n# Rollback to previous version\nwrangler rollback\n\n# Rollback to specific version\nwrangler rollback <VERSION_ID>\n```\n\n---\n\n## KV (Key-Value Store)\n\n### Manage Namespaces\n\n```bash\n# Create namespace\nwrangler kv namespace create MY_KV\n\n# List namespaces\nwrangler kv namespace list\n\n# Delete namespace\nwrangler kv namespace delete --namespace-id <ID>\n```\n\n### Manage Keys\n\n```bash\n# Put value\nwrangler kv key put --namespace-id <ID> \"key\" \"value\"\n\n# Put with expiration (seconds)\nwrangler kv key put --namespace-id <ID> \"key\" \"value\" --expiration-ttl 3600\n\n# Get value\nwrangler kv key get --namespace-id <ID> \"key\"\n\n# List keys\nwrangler kv key list --namespace-id <ID>\n\n# Delete key\nwrangler kv key delete --namespace-id <ID> \"key\"\n\n# Bulk put from JSON\nwrangler kv bulk put --namespace-id <ID> data.json\n```\n\n### Config Binding\n\n```jsonc\n{\n  \"kv_namespaces\": [\n    { \"binding\": \"CACHE\", \"id\": \"<NAMESPACE_ID>\" }\n  ]\n}\n```\n\n---\n\n## R2 (Object Storage)\n\n### Manage Buckets\n\n```bash\n# Create bucket\nwrangler r2 bucket create my-bucket\n\n# Create with location hint\nwrangler r2 bucket create my-bucket --location wnam\n\n# List buckets\nwrangler r2 bucket list\n\n# Get bucket info\nwrangler r2 bucket info my-bucket\n\n# Delete bucket\nwrangler r2 bucket delete my-bucket\n```\n\n### Manage Objects\n\n```bash\n# Upload object\nwrangler r2 object put my-bucket/path/file.txt --file ./local-file.txt\n\n# Download object\nwrangler r2 object get my-bucket/path/file.txt\n\n# Delete object\nwrangler r2 object delete my-bucket/path/file.txt\n```\n\n### Config Binding\n\n```jsonc\n{\n  \"r2_buckets\": [\n    { \"binding\": \"ASSETS\", \"bucket_name\": \"my-bucket\" }\n  ]\n}\n```\n\n---\n\n## D1 (SQL Database)\n\n### Manage Databases\n\n```bash\n# Create database\nwrangler d1 create my-database\n\n# Create with location\nwrangler d1 create my-database --location wnam\n\n# List databases\nwrangler d1 list\n\n# Get database info\nwrangler d1 info my-database\n\n# Delete database\nwrangler d1 delete my-database\n```\n\n### Execute SQL\n\n```bash\n# Execute SQL command (remote)\nwrangler d1 execute my-database --remote --command \"SELECT * FROM users\"\n\n# Execute SQL file (remote)\nwrangler d1 execute my-database --remote --file ./schema.sql\n\n# Execute locally\nwrangler d1 execute my-database --local --command \"SELECT * FROM users\"\n```\n\n### Migrations\n\n```bash\n# Create migration\nwrangler d1 migrations create my-database create_users_table\n\n# List pending migrations\nwrangler d1 migrations list my-database --local\n\n# Apply migrations locally\nwrangler d1 migrations apply my-database --local\n\n# Apply migrations to remote\nwrangler d1 migrations apply my-database --remote\n```\n\n### Export/Backup\n\n```bash\n# Export schema and data\nwrangler d1 export my-database --remote --output backup.sql\n\n# Export schema only\nwrangler d1 export my-database --remote --output schema.sql --no-data\n```\n\n### Config Binding\n\n```jsonc\n{\n  \"d1_databases\": [\n    {\n      \"binding\": \"DB\",\n      \"database_name\": \"my-database\",\n      \"database_id\": \"<DATABASE_ID>\",\n      \"migrations_dir\": \"./migrations\"\n    }\n  ]\n}\n```\n\n---\n\n## Vectorize (Vector Database)\n\n### Manage Indexes\n\n```bash\n# Create index with dimensions\nwrangler vectorize create my-index --dimensions 768 --metric cosine\n\n# Create with preset (auto-configures dimensions/metric)\nwrangler vectorize create my-index --preset @cf/baai/bge-base-en-v1.5\n\n# List indexes\nwrangler vectorize list\n\n# Get index info\nwrangler vectorize get my-index\n\n# Delete index\nwrangler vectorize delete my-index\n```\n\n### Manage Vectors\n\n```bash\n# Insert vectors from NDJSON file\nwrangler vectorize insert my-index --file vectors.ndjson\n\n# Query vectors\nwrangler vectorize query my-index --vector \"[0.1, 0.2, ...]\" --top-k 10\n```\n\n### Config Binding\n\n```jsonc\n{\n  \"vectorize\": [\n    { \"binding\": \"SEARCH_INDEX\", \"index_name\": \"my-index\" }\n  ]\n}\n```\n\n---\n\n## Hyperdrive (Database Accelerator)\n\n### Manage Configs\n\n```bash\n# Create config\nwrangler hyperdrive create my-hyperdrive \\\n  --origin-host db.example.com \\\n  --origin-port 5432 \\\n  --database my-database \\\n  --origin-user db-user \\\n  --origin-password \"$DB_PASSWORD\"\n\n# Or using a connection string from an environment variable\nwrangler hyperdrive create my-hyperdrive \\\n  --connection-string \"$HYPERDRIVE_CONNECTION_STRING\"\n\n# List configs\nwrangler hyperdrive list\n\n# Get config details\nwrangler hyperdrive get <HYPERDRIVE_ID>\n\n# Update config\nwrangler hyperdrive update <HYPERDRIVE_ID> \\\n  --origin-password \"$DB_PASSWORD\"\n\n# Delete config\nwrangler hyperdrive delete <HYPERDRIVE_ID>\n```\n\n### Config Binding\n\n```jsonc\n{\n  \"compatibility_flags\": [\"nodejs_compat\"],\n  \"hyperdrive\": [\n    { \"binding\": \"HYPERDRIVE\", \"id\": \"<HYPERDRIVE_ID>\" }\n  ]\n}\n```\n\n---\n\n## Workers AI\n\n### List Models\n\n```bash\n# List available models\nwrangler ai models\n\n# List finetunes\nwrangler ai finetune list\n```\n\n### Config Binding\n\n```jsonc\n{\n  \"ai\": { \"binding\": \"AI\" }\n}\n```\n\n**Note**: Workers AI always runs remotely and incurs usage charges even in local dev.\n\n---\n\n## Queues\n\n### Manage Queues\n\n```bash\n# Create queue\nwrangler queues create my-queue\n\n# List queues\nwrangler queues list\n\n# Delete queue\nwrangler queues delete my-queue\n\n# Add consumer to queue\nwrangler queues consumer add my-queue my-worker\n\n# Remove consumer\nwrangler queues consumer remove my-queue my-worker\n```\n\n### Config Binding\n\n```jsonc\n{\n  \"queues\": {\n    \"producers\": [\n      { \"binding\": \"MY_QUEUE\", \"queue\": \"my-queue\" }\n    ],\n    \"consumers\": [\n      {\n        \"queue\": \"my-queue\",\n        \"max_batch_size\": 10,\n        \"max_batch_timeout\": 30\n      }\n    ]\n  }\n}\n```\n\n---\n\n## Containers\n\n### Build and Push Images\n\n```bash\n# Build container image\nwrangler containers build -t my-app:latest .\n\n# Build and push in one command\nwrangler containers build -t my-app:latest . --push\n\n# Push existing image to Cloudflare registry\nwrangler containers push my-app:latest\n```\n\n### Manage Containers\n\n```bash\n# List containers\nwrangler containers list\n\n# Get container info\nwrangler containers info <CONTAINER_ID>\n\n# Delete container\nwrangler containers delete <CONTAINER_ID>\n```\n\n### Manage Images\n\n```bash\n# List images in registry\nwrangler containers images list\n\n# Delete image\nwrangler containers images delete my-app:latest\n```\n\n### Manage External Registries\n\n> **Security**: Never hardcode registry credentials in commands. Use environment variables.\n\n```bash\n# List configured registries\nwrangler containers registries list\n\n# Configure external registry (e.g., ECR)\nwrangler containers registries configure <DOMAIN> \\\n  --aws-access-key-id \"$AWS_ACCESS_KEY_ID\"\n\n# Configure DockerHub\nwrangler containers registries configure <DOMAIN> \\\n  --dockerhub-username \"$DOCKERHUB_USERNAME\"\n\n# Delete registry configuration\nwrangler containers registries delete <DOMAIN>\n```\n\n---\n\n## Workflows\n\n### Manage Workflows\n\n```bash\n# List workflows\nwrangler workflows list\n\n# Describe workflow\nwrangler workflows describe my-workflow\n\n# Trigger workflow instance\nwrangler workflows trigger my-workflow\n\n# Trigger with parameters\nwrangler workflows trigger my-workflow --params '{\"key\": \"value\"}'\n\n# Delete workflow\nwrangler workflows delete my-workflow\n```\n\n### Manage Workflow Instances\n\n```bash\n# List instances\nwrangler workflows instances list my-workflow\n\n# Describe instance\nwrangler workflows instances describe my-workflow <INSTANCE_ID>\n\n# Terminate instance\nwrangler workflows instances terminate my-workflow <INSTANCE_ID>\n```\n\n### Config Binding\n\n```jsonc\n{\n  \"workflows\": [\n    {\n      \"binding\": \"MY_WORKFLOW\",\n      \"name\": \"my-workflow\",\n      \"class_name\": \"MyWorkflow\"\n    }\n  ]\n}\n```\n\n---\n\n## Pipelines\n\n### Manage Pipelines\n\n```bash\n# Create pipeline\nwrangler pipelines create my-pipeline --r2 my-bucket\n\n# List pipelines\nwrangler pipelines list\n\n# Show pipeline details\nwrangler pipelines show my-pipeline\n\n# Update pipeline\nwrangler pipelines update my-pipeline --batch-max-mb 100\n\n# Delete pipeline\nwrangler pipelines delete my-pipeline\n```\n\n### Config Binding\n\n```jsonc\n{\n  \"pipelines\": [\n    { \"binding\": \"MY_PIPELINE\", \"pipeline\": \"my-pipeline\" }\n  ]\n}\n```\n\n---\n\n## Secrets Store\n\n### Manage Stores\n\n```bash\n# Create store\nwrangler secrets-store store create my-store\n\n# List stores\nwrangler secrets-store store list\n\n# Delete store\nwrangler secrets-store store delete <STORE_ID>\n```\n\n### Manage Secrets in Store\n\n```bash\n# Add secret to store\nwrangler secrets-store secret put <STORE_ID> my-secret\n\n# List secrets in store\nwrangler secrets-store secret list <STORE_ID>\n\n# Get secret\nwrangler secrets-store secret get <STORE_ID> my-secret\n\n# Delete secret from store\nwrangler secrets-store secret delete <STORE_ID> my-secret\n```\n\n### Config Binding\n\n```jsonc\n{\n  \"secrets_store_secrets\": [\n    {\n      \"binding\": \"MY_SECRET\",\n      \"store_id\": \"<STORE_ID>\",\n      \"secret_name\": \"my-secret\"\n    }\n  ]\n}\n```\n\n---\n\n## Pages (Frontend Deployment)\n\n```bash\n# Create Pages project\nwrangler pages project create my-site\n\n# Deploy directory to Pages\nwrangler pages deploy ./dist\n\n# Deploy with specific branch\nwrangler pages deploy ./dist --branch main\n\n# List deployments\nwrangler pages deployment list --project-name my-site\n```\n\n---\n\n## Observability\n\n### Tail Logs\n\n```bash\n# Stream live logs\nwrangler tail\n\n# Tail specific Worker\nwrangler tail my-worker\n\n# Filter by status\nwrangler tail --status error\n\n# Filter by search term\nwrangler tail --search \"error\"\n\n# JSON output\nwrangler tail --format json\n```\n\n### Config Logging\n\n```jsonc\n{\n  \"observability\": {\n    \"enabled\": true,\n    \"head_sampling_rate\": 1\n  }\n}\n```\n\n---\n\n## Testing\n\n### Local Testing with Vitest\n\n```bash\nnpm install -D @cloudflare/vitest-pool-workers vitest\n```\n\n`vitest.config.ts`:\n```typescript\nimport { defineWorkersConfig } from \"@cloudflare/vitest-pool-workers/config\";\n\nexport default defineWorkersConfig({\n  test: {\n    poolOptions: {\n      workers: {\n        wrangler: { configPath: \"./wrangler.jsonc\" },\n      },\n    },\n  },\n});\n```\n\n### Test Scheduled Events\n\n```bash\n# Enable in dev\nwrangler dev --test-scheduled\n\n# Trigger via HTTP\ncurl http://localhost:8787/__scheduled\n```\n\n---\n\n## Troubleshooting\n\n### Common Issues\n\n| Issue | Solution |\n|-------|----------|\n| `command not found: wrangler` | Install: `npm install -D wrangler` |\n| Auth errors | Run `wrangler login` |\n| Startup time limit exceeded | Run `wrangler check startup` to profile startup and generate CPU profiles |\n| Type errors after config change | Run `wrangler types` |\n| Local storage not persisting | Check `.wrangler/state` directory |\n| Binding undefined in Worker | Verify binding name matches config exactly |\n\n### Debug Commands\n\n```bash\n# Check auth status\nwrangler whoami\n\n# Profile Worker startup time\nwrangler check startup\n\n# View config schema\nwrangler docs configuration\n```\n\n---\n\n## Best Practices\n\n1. **Version control `wrangler.jsonc`**: Treat as source of truth for Worker config.\n2. **Use automatic provisioning**: Omit resource IDs for auto-creation on deploy.\n3. **Run `wrangler types` in CI**: Add to build step to catch binding mismatches.\n4. **Use environments**: Separate staging/production with `env.staging`, `env.production`.\n5. **Set `compatibility_date`**: Update quarterly to get new runtime features.\n6. **Use `.dev.vars` for local secrets**: Never commit secrets to config.\n7. **Test locally first**: `wrangler dev` with local bindings before deploying.\n8. **Use `--dry-run` before major deploys**: Validate changes without deployment.\n9. **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.\n","contentSource":"skills.sh/api/download/cloudflare/skills/wrangler","contentFetchedAt":"2026-07-27T08:59:25.303Z"}