INTEGRITY Cloudflare Docs

Configuration

Wrangler optionally uses a configuration file to customize the development and deployment setup for a Worker.

It is best practice to treat Wrangler's configuration file as the source of truth for configuring a Worker.

Sample Wrangler configuration

{
	"$schema": "./node_modules/wrangler/config-schema.json",
	// Top-level configuration
	"name": "my-worker",
	"main": "src/index.js",
	// Set this to today's date
	"compatibility_date": "2026-08-28",
	"workers_dev": false,
	"route": {
		"pattern": "example.org/*",
		"zone_name": "example.org",
	},
	"kv_namespaces": [
		{
			"binding": "<MY_NAMESPACE>",
			"id": "<KV_ID>",
		},
	],
	"env": {
		"staging": {
			"name": "my-worker-staging",
			"route": {
				"pattern": "staging.example.org/*",
				"zone_name": "example.org",
			},
			"kv_namespaces": [
				{
					"binding": "<MY_NAMESPACE>",
					"id": "<STAGING_KV_ID>",
				},
			],
		},
	},
}
"$schema" = "./node_modules/wrangler/config-schema.json"
name = "my-worker"
main = "src/index.js"
# Set this to today's date
compatibility_date = "2026-08-28"
workers_dev = false

[route]
pattern = "example.org/*"
zone_name = "example.org"

[[kv_namespaces]]
binding = "<MY_NAMESPACE>"
id = "<KV_ID>"

[env.staging]
name = "my-worker-staging"

  [env.staging.route]
  pattern = "staging.example.org/*"
  zone_name = "example.org"

  [[env.staging.kv_namespaces]]
  binding = "<MY_NAMESPACE>"
  id = "<STAGING_KV_ID>"

Environments

You can define different configurations for a Worker using Wrangler environments. There is a default (top-level) environment and you can create named environments that provide environment-specific configuration.

These are defined under [env.<name>] keys, such as [env.staging] which you can then preview or deploy with the -e / --env flag in the wrangler commands like npx wrangler deploy --env staging.

The majority of keys are inheritable, meaning that top-level configuration can be used in environments. Bindings, such as vars or kv_namespaces, are not inheritable and need to be defined explicitly.

Further, there are a few keys that can only appear at the top-level.

Automatic provisioning

Beta

Wrangler can automatically provision resources for you when you deploy your Worker without you having to create them ahead of time.

This currently works for the following resources: KV, R2, D1, Flagship, AI Search, Agent Memory, Dispatch Namespaces and Queues.

To use this feature, add bindings to your configuration file without adding resource IDs, or in the case of R2, a bucket name. Resources will be created with the name of your worker as the prefix.

{
	"kv_namespaces": [
		{
			"binding": "<MY_KV_NAMESPACE>",
		},
	],
}
[[kv_namespaces]]
binding = "<MY_KV_NAMESPACE>"

When you run wrangler dev, local resources will automatically be created which persist between runs. When you run wrangler deploy, resources will be created for you, and their IDs will be written back to your configuration file.

If you deploy a worker with resources and no resource IDs from the dashboard (for example, via GitHub), resources will be created, but their IDs will only be accessible via the dashboard. Currently, these resource IDs will not be written back to your repository.

Top-level only keys

Top-level keys apply to the Worker as a whole (and therefore all environments). They cannot be defined within named environments.

Inheritable keys

Inheritable keys are configurable at the top-level, and can be inherited (or overridden) by environment-specific configuration.

Non-inheritable keys

Non-inheritable keys are configurable at the top-level, but cannot be inherited by environments and must be specified for each environment.

Types of routes

There are three types of routes: Custom Domains, routes, and workers.dev.

Custom Domains

Custom Domains allow you to connect your Worker to a domain or subdomain, without having to make changes to your DNS settings or perform any certificate management.

Example:

{
	"routes": [
		{
			"pattern": "shop.example.com",
			"custom_domain": true,
		},
	],
}
[[routes]]
pattern = "shop.example.com"
custom_domain = true

Routes

Routes allow users to map a URL pattern to a Worker. A route can be configured as a zone ID route, a zone name route, or a simple route.

Zone ID route

Example:

{
	"routes": [
		{
			"pattern": "subdomain.example.com/*",
			"zone_id": "<YOUR_ZONE_ID>",
		},
	],
}
[[routes]]
pattern = "subdomain.example.com/*"
zone_id = "<YOUR_ZONE_ID>"

Zone name route

Example:

{
	"routes": [
		{
			"pattern": "subdomain.example.com/*",
			"zone_name": "example.com",
		},
	],
}
[[routes]]
pattern = "subdomain.example.com/*"
zone_name = "example.com"

Simple route

This is a simple route that only requires a pattern.

Example:

{
	"route": "example.com/*",
}
route = "example.com/*"

workers.dev

Cloudflare Workers accounts come with a workers.dev subdomain that is configurable in the Cloudflare dashboard.

{
	"workers_dev": false,
}
workers_dev = false

Triggers

Triggers allow you to define the cron expression to invoke your Worker's scheduled function. Refer to Supported cron expressions.

Example:

{
	"triggers": {
		"crons": ["* * * * *"],
	},
}
[triggers]
crons = [ "* * * * *" ]

Observability

The Observability setting allows you to automatically ingest, store, filter, and analyze logging data emitted from Cloudflare Workers directly from your Cloudflare Worker's dashboard.

Example:

{
	"observability": {
		"enabled": true,
		"head_sampling_rate": 0.1, // 10% of requests are logged
	},
}
[observability]
enabled = true
head_sampling_rate = 0.1

Custom builds

You can configure a custom build step that will be run before your Worker is deployed. Refer to Custom builds.

Example:

{
	"build": {
		"command": "npm run build",
		"cwd": "build_cwd",
		"watch_dir": "build_watch_dir",
	},
}
[build]
command = "npm run build"
cwd = "build_cwd"
watch_dir = "build_watch_dir"

Limits

You can impose limits on your Worker's behavior at runtime. Limits are only supported for the Standard Usage Model. Limits are only enforced when deployed to Cloudflare's network, not in local development. The CPU limit can be set to a maximum of 300,000 milliseconds (5 minutes).

Each isolate has some built-in flexibility to allow for cases where your Worker infrequently runs over the configured limit. If your Worker starts hitting the limit consistently, its execution will be terminated according to the limit configured.


Example:

{
	"limits": {
		"cpu_ms": 100,
		"subrequests": 150,
	},
}
[limits]
cpu_ms = 100
subrequests = 150

Bindings

Browser Run

The Workers Browser Run API allows developers to programmatically control and interact with a headless browser instance and create automation flows for their applications and products.

A browser binding will provide your Worker with an authenticated endpoint to interact with a dedicated Chromium browser instance.

Example:

{
	"browser": {
		"binding": "<BINDING_NAME>",
	},
}
[browser]
binding = "<BINDING_NAME>"

D1 databases

D1 is Cloudflare's serverless SQL database. A Worker can query a D1 database (or databases) by creating a binding to each database for D1 Workers Binding API.

To bind D1 databases to your Worker, assign an array of the below object to the [[d1_databases]] key.

Example:

{
	"d1_databases": [
		{
			"binding": "<BINDING_NAME>",
			"database_name": "<DATABASE_NAME>",
			"database_id": "<DATABASE_ID>",
		},
	],
}
[[d1_databases]]
binding = "<BINDING_NAME>"
database_name = "<DATABASE_NAME>"
database_id = "<DATABASE_ID>"

Dispatch namespace bindings (Workers for Platforms)

Dispatch namespace bindings allow for communication between a dynamic dispatch Worker and a dispatch namespace. Dispatch namespace bindings are used in Workers for Platforms. Workers for Platforms helps you deploy serverless functions programmatically on behalf of your customers.

{
	"dispatch_namespaces": [
		{
			"binding": "<BINDING_NAME>",
			"namespace": "<NAMESPACE_NAME>",
			"outbound": {
				"service": "<WORKER_NAME>",
				"parameters": ["params_object"],
			},
		},
	],
}
[[dispatch_namespaces]]
binding = "<BINDING_NAME>"
namespace = "<NAMESPACE_NAME>"

  [dispatch_namespaces.outbound]
  service = "<WORKER_NAME>"
  parameters = [ "params_object" ]

Durable Objects

Durable Objects provide low-latency coordination and consistent storage for the Workers platform.

To bind Durable Objects to your Worker, assign an array of the below object to the durable_objects.bindings key.

Example:

{
	"durable_objects": {
		"bindings": [
			{
				"name": "<BINDING_NAME>",
				"class_name": "<CLASS_NAME>",
			},
		],
	},
}
[[durable_objects.bindings]]
name = "<BINDING_NAME>"
class_name = "<CLASS_NAME>"

Exports

The exports field declares the Durable Object classes this Worker exports and their lifecycle state. Refer to Durable Object class exports.

Each entry in exports is keyed by Durable Object class name. The fields on each entry are:

Example:

{
	"exports": {
		"MyDurableObject": {
			"type": "durable-object",
			"storage": "sqlite",
		},
		"OldClass": {
			"type": "durable-object",
			"state": "deleted",
		},
		"OldName": {
			"type": "durable-object",
			"state": "renamed",
			"renamed_to": "NewName",
		},
		"NewName": {
			"type": "durable-object",
			"storage": "sqlite",
		},
	},
}
[exports.MyDurableObject]
type = "durable-object"
storage = "sqlite"

[exports.OldClass]
type = "durable-object"
state = "deleted"

[exports.OldName]
type = "durable-object"
state = "renamed"
renamed_to = "NewName"

[exports.NewName]
type = "durable-object"
storage = "sqlite"

Migrations

When making changes to your Durable Object classes on a Worker that uses the legacy migrations array, you must perform a migration. Refer to Durable Object class migrations (legacy).

Example:

{
	"migrations": [
		{
			"tag": "v1",
			"new_sqlite_classes": [
				// Array of new classes
				"DurableObjectExample",
			],
		},
		{
			"tag": "v2", // Should be unique for each entry
			"renamed_classes": [
				// Array of rename directives
				{
					"from": "DurableObjectExample",
					"to": "UpdatedName",
				},
			],
			"deleted_classes": [
				// Array of deleted class names
				"DeprecatedClass",
			],
		},
	],
}
[[migrations]]
tag = "v1"
new_sqlite_classes = [ "DurableObjectExample" ]

[[migrations]]
tag = "v2"
deleted_classes = [ "DeprecatedClass" ]

  [[migrations.renamed_classes]]
  from = "DurableObjectExample"
  to = "UpdatedName"

Email bindings

You can send an email about your Worker's activity from your Worker to an email address verified on Email Routing. This is useful for when you want to know about certain types of events being triggered, for example.

Before you can bind an email address to your Worker, you need to enable Email Routing and have at least one verified email address. Then, assign an array to the object (send_email) with the type of email binding you need.

You can add one or more types of bindings to your Wrangler file. However, each attribute must be on its own line:

{
	"send_email": [
		{
			"name": "<NAME_FOR_BINDING1>"
		},
		{
			"name": "<NAME_FOR_BINDING2>",
			"destination_address": "<YOUR_EMAIL>@example.com"
		},
		{
			"name": "<NAME_FOR_BINDING3>",
			"allowed_destination_addresses": [
				"<YOUR_EMAIL>@example.com",
				"<YOUR_EMAIL2>@example.com"
			]
		}
	]
}
[[send_email]]
name = "<NAME_FOR_BINDING1>"

[[send_email]]
name = "<NAME_FOR_BINDING2>"
destination_address = "<YOUR_EMAIL>@example.com"

[[send_email]]
name = "<NAME_FOR_BINDING3>"
allowed_destination_addresses = [ "<YOUR_EMAIL>@example.com", "<YOUR_EMAIL2>@example.com" ]

Environment variables

Environment variables are a type of binding that allow you to attach text strings or JSON values to your Worker.

Example:

{
	"$schema": "./node_modules/wrangler/config-schema.json",
	"name": "my-worker-dev",
	"vars": {
		"API_HOST": "example.com",
		"API_ACCOUNT_ID": "example_user",
		"SERVICE_X_DATA": {
			"URL": "service-x-api.dev.example",
			"MY_ID": 123
		}
	}
}
"$schema" = "./node_modules/wrangler/config-schema.json"
name = "my-worker-dev"

[vars]
API_HOST = "example.com"
API_ACCOUNT_ID = "example_user"

  [vars.SERVICE_X_DATA]
  URL = "service-x-api.dev.example"
  MY_ID = 123

Hyperdrive

Hyperdrive bindings allow you to interact with and query any Postgres database from within a Worker.

Example:

{
	// required for database drivers to function
	"compatibility_flags": ["nodejs_compat_v2"],
	"hyperdrive": [
		{
			"binding": "<BINDING_NAME>",
			"id": "<ID>",
		},
	],
}
compatibility_flags = [ "nodejs_compat_v2" ]

[[hyperdrive]]
binding = "<BINDING_NAME>"
id = "<ID>"

Images

Cloudflare Images lets you make transformation requests to optimize, resize, and manipulate images stored in remote sources.

To bind Images to your Worker, assign an array of the below object to the images key.

binding (required). The name of the binding used to refer to the Images API.

{
	"images": {
		"binding": "IMAGES", // i.e. available in your Worker on env.IMAGES
	},
}
[images]
binding = "IMAGES"

KV namespaces

Workers KV is a global, low-latency, key-value data store. It stores data in a small number of centralized data centers, then caches that data in Cloudflare’s data centers after access.

To bind KV namespaces to your Worker, assign an array of the below object to the kv_namespaces key.

Example:

{
	"kv_namespaces": [
		{
			"binding": "<BINDING_NAME1>",
			"id": "<NAMESPACE_ID1>",
		},
		{
			"binding": "<BINDING_NAME2>",
			"id": "<NAMESPACE_ID2>",
		},
	],
}
[[kv_namespaces]]
binding = "<BINDING_NAME1>"
id = "<NAMESPACE_ID1>"

[[kv_namespaces]]
binding = "<BINDING_NAME2>"
id = "<NAMESPACE_ID2>"

AI Search namespaces

AI Search is Cloudflare's managed search service. A namespace is a logical grouping of AI Search instances. The binding grants full access to all instances within the namespace.

To bind AI Search namespaces to your Worker, assign an array of the below object to the ai_search_namespaces key.

Example:

{
	"ai_search_namespaces": [
		{
			"binding": "<BINDING_NAME>",
			"namespace": "default",
		},
	],
}
[[ai_search_namespaces]]
binding = "<BINDING_NAME>"
namespace = "default"

AI Search instances

To bind directly to a pre-existing AI Search instance in the default namespace, assign an array of the below object to the ai_search key. This binding does not support namespace-level operations like list(), create(), or delete().

Example:

{
	"ai_search": [
		{
			"binding": "<BINDING_NAME>",
			"instance_name": "<INSTANCE_NAME>",
		},
	],
}
[[ai_search]]
binding = "<BINDING_NAME>"
instance_name = "<INSTANCE_NAME>"

Queues

Queues is Cloudflare's global message queueing service, providing guaranteed delivery and message batching. To interact with a queue with Workers, you need a producer Worker to send messages to the queue and a consumer Worker to pull batches of messages out of the Queue. A single Worker can produce to and consume from multiple Queues.

To bind Queues to your producer Worker, assign an array of the below object to the [[queues.producers]] key.

Example:

{
	"queues": {
		"producers": [
			{
				"binding": "<BINDING_NAME>",
				"queue": "<QUEUE_NAME>",
				"delivery_delay": 60, // Delay messages by 60 seconds before they are delivered to a consumer
			},
		],
	},
}
[[queues.producers]]
binding = "<BINDING_NAME>"
queue = "<QUEUE_NAME>"
delivery_delay = 60

To bind Queues to your consumer Worker, assign an array of the below object to the [[queues.consumers]] key.

Example:

{
	"queues": {
		"consumers": [
			{
				"queue": "my-queue",
				"max_batch_size": 10,
				"max_batch_timeout": 30,
				"max_retries": 10,
				"dead_letter_queue": "my-queue-dlq",
				"max_concurrency": 5,
				"retry_delay": 120, // Delay retried messages by 2 minutes before re-attempting delivery
			},
		],
	},
}
[[queues.consumers]]
queue = "my-queue"
max_batch_size = 10
max_batch_timeout = 30
max_retries = 10
dead_letter_queue = "my-queue-dlq"
max_concurrency = 5
retry_delay = 120

R2 buckets

Cloudflare R2 Storage allows developers to store large amounts of unstructured data without the costly egress bandwidth fees associated with typical cloud storage services.

To bind R2 buckets to your Worker, assign an array of the below object to the r2_buckets key.

Example:

{
	"r2_buckets": [
		{
			"binding": "<BINDING_NAME1>",
			"bucket_name": "<BUCKET_NAME1>",
		},
		{
			"binding": "<BINDING_NAME2>",
			"bucket_name": "<BUCKET_NAME2>",
		},
	],
}
[[r2_buckets]]
binding = "<BINDING_NAME1>"
bucket_name = "<BUCKET_NAME1>"

[[r2_buckets]]
binding = "<BINDING_NAME2>"
bucket_name = "<BUCKET_NAME2>"

Vectorize indexes

A Vectorize index allows you to insert and query vector embeddings for semantic search, classification and other vector search use-cases.

To bind Vectorize indexes to your Worker, assign an array of the below object to the vectorize key.

Example:

{
	"vectorize": [
		{
			"binding": "<BINDING_NAME>",
			"index_name": "<INDEX_NAME>",
		},
	],
}
[[vectorize]]
binding = "<BINDING_NAME>"
index_name = "<INDEX_NAME>"

Service bindings

A service binding allows you to send HTTP requests to another Worker without those requests going over the Internet. The request immediately invokes the downstream Worker, reducing latency as compared to a request to a third-party service. Refer to About Service Bindings.

To bind other Workers to your Worker, assign an array of the below object to the services key.

Example:

{
	"services": [
		{
			"binding": "<BINDING_NAME>",
			"service": "<WORKER_NAME>",
			"entrypoint": "<ENTRYPOINT_NAME>",
		},
	],
}
[[services]]
binding = "<BINDING_NAME>"
service = "<WORKER_NAME>"
entrypoint = "<ENTRYPOINT_NAME>"

Static assets

Refer to Assets.

Analytics Engine Datasets

Workers Analytics Engine provides analytics, observability and data logging from Workers. Write data points to your Worker binding then query the data using the SQL API.

To bind Analytics Engine datasets to your Worker, assign an array of the below object to the analytics_engine_datasets key.

Example:

{
	"analytics_engine_datasets": [
		{
			"binding": "<BINDING_NAME>",
			"dataset": "<DATASET_NAME>",
		},
	],
}
[[analytics_engine_datasets]]
binding = "<BINDING_NAME>"
dataset = "<DATASET_NAME>"

mTLS Certificates

To communicate with origins that require client authentication, a Worker can present a certificate for mTLS in subrequests. Wrangler provides the mtls-certificate command to upload and manage these certificates.

To create a binding to an mTLS certificate for your Worker, assign an array of objects with the following shape to the mtls_certificates key.

Example of a Wrangler configuration file that includes an mTLS certificate binding:

{
	"mtls_certificates": [
		{
			"binding": "<BINDING_NAME1>",
			"certificate_id": "<CERTIFICATE_ID1>",
		},
		{
			"binding": "<BINDING_NAME2>",
			"certificate_id": "<CERTIFICATE_ID2>",
		},
	],
}
[[mtls_certificates]]
binding = "<BINDING_NAME1>"
certificate_id = "<CERTIFICATE_ID1>"

[[mtls_certificates]]
binding = "<BINDING_NAME2>"
certificate_id = "<CERTIFICATE_ID2>"

mTLS certificate bindings can then be used at runtime to communicate with secured origins via their fetch method.

Workers AI

Workers AI allows you to run machine learning models, on the Cloudflare network, from your own code – whether that be from Workers, Pages, or anywhere via REST API.

Unlike other bindings, this binding is limited to one AI binding per Worker project.

Example:

{
	"ai": {
		"binding": "AI", // available in your Worker code on `env.AI`
	},
}
[ai]
binding = "AI"

Workflows

Workflows allow you to build durable, multi-step applications using the Workers platform. A Workflow binding enables your Worker to create and manage Workflow instances programmatically.

To bind Workflows to your Worker, assign an array of the below object to the workflows key.

Example:

{
	"workflows": [
		{
			"binding": "<BINDING_NAME>",
			"name": "<WORKFLOW_NAME>",
			"class_name": "<CLASS_NAME>",
		},
	],
}
[[workflows]]
binding = "<BINDING_NAME>"
name = "<WORKFLOW_NAME>"
class_name = "<CLASS_NAME>"

Assets

Static assets allows developers to run front-end websites on Workers. You can configure the directory of assets, an optional runtime binding, and routing configuration options.

You can only configure one collection of assets per Worker.

The following options are available under the assets key.

Example:

{
	"assets": {
		"directory": "./public",
		"binding": "ASSETS",
		"html_handling": "force-trailing-slash",
		"not_found_handling": "404-page",
	},
}
[assets]
directory = "./public"
binding = "ASSETS"
html_handling = "force-trailing-slash"
not_found_handling = "404-page"

You can also configure run_worker_first with an array of route patterns:

{
	"assets": {
		"directory": "./public",
		"binding": "ASSETS",
		"run_worker_first": [
			"/api/*", // API calls go to Worker first
			"!/api/docs/*", // EXCEPTION: For /api/docs/*, try static assets first
		],
	},
}
[assets]
directory = "./public"
binding = "ASSETS"
run_worker_first = [ "/api/*", "!/api/docs/*" ]

Containers

You can define Containers to run alongside your Worker using the containers field.

The following options are available:

{
	"containers": [
		{
			"class_name": "MyContainer",
			"image": "./Dockerfile",
			"max_instances": 10,
			"instance_type": "basic", // Optional, defaults to "lite"
			"image_vars": {
				"FOO": "BAR",
			},
			"constraints": {
				"regions": ["ENAM", "WNAM"],
				"jurisdiction": "fedramp",
			},
		},
	],
	"durable_objects": {
		"bindings": [
			{
				"name": "MY_CONTAINER",
				"class_name": "MyContainer",
			},
		],
	},
	"migrations": [
		{
			"tag": "v1",
			"new_sqlite_classes": ["MyContainer"],
		},
	],
}
[[containers]]
class_name = "MyContainer"
image = "./Dockerfile"
max_instances = 10
instance_type = "basic"

  [containers.image_vars]
  FOO = "BAR"

  [containers.constraints]
  regions = [ "ENAM", "WNAM" ]
  jurisdiction = "fedramp"

[[durable_objects.bindings]]
name = "MY_CONTAINER"
class_name = "MyContainer"

[[migrations]]
tag = "v1"
new_sqlite_classes = [ "MyContainer" ]

Custom Instance Types

In place of the named instance types, you can set a custom instance type by individually configuring vCPU, memory, and disk. See the limits documentation for constraints on custom instance types.

The following options are available:

{
	"containers": [
		{
			"image": "./Dockerfile",
			"instance_type": {
				"vcpu": 1,
				"memory_mib": 1024,
				"disk_mb": 4000,
			},
		},
	],
}
[[containers]]
image = "./Dockerfile"

  [containers.instance_type]
  vcpu = 1
  memory_mib = 1_024
  disk_mb = 4_000

SSH

Configuration for SSH access to a Container instance through Wrangler. For a guide on connecting to Containers via SSH, refer to SSH.

The following options are available:

Authorized keys

An authorized key is a public key that can be used to SSH into a Container.

The following are properties of a key:

Bundling

Wrangler can operate in two modes: the default bundling mode and --no-bundle mode. In bundling mode, Wrangler will traverse all the imports of your code and generate a single JavaScript "entry-point" file. Imported source code is "inlined/bundled" into this entry-point file.

It is also possible to include additional modules into your Worker, which are uploaded alongside the entry-point. You specify which additional modules should be included into your Worker using the rules key, making these modules available to be imported when your Worker is invoked. The rules key will be an array of the below object.

Example:

{
	"rules": [
		{
			"type": "Text",
			"globs": ["**/*.md"],
			"fallthrough": true,
		},
	],
}
[[rules]]
type = "Text"
globs = [ "**/*.md" ]
fallthrough = true

Importing modules within a Worker

You can import and refer to these modules within your Worker, like so:

index.js
import markdown from "./example.md";

export default {
	async fetch() {
		return new Response(markdown);
	},
};

Find additional modules

Normally Wrangler will only include additional modules that are statically imported in your source code as in the example above. By setting find_additional_modules to true in your configuration file, Wrangler will traverse the file tree below base_dir. Any files that match rules will also be included as unbundled, external modules in the deployed Worker. base_dir defaults to the directory containing your main entrypoint.

See https://developers.cloudflare.com/workers/wrangler/bundling/ for more details and examples.

Python Workers

By default, Python Workers bundle the files and folders in python_modules at the root of your Worker (alongside your wrangler config file). The files in this directory represent your vendored packages and is where the pywrangler tool copies packages into. In some cases, you may find that the files in this folder are too large and if your worker doesn't require them then they just grow your bundle size for no reason.

To fix this, you can exclude certain files from being included. To do this use the python_modules.excludes option, for example:

{
	"python_modules": {
		"excludes": ["**/*.pyc", "**/__pycache__"],
	},
}
[python_modules]
excludes = [ "**/*.pyc", "**/__pycache__" ]

This will exclude any .pyc files and __pycache__ directories inside any subdirectory in python_modules.

By default, python_modules.excludes is set to ["**/*.pyc"], so be sure to include this when setting it to a different value.

Local development settings

You can configure various aspects of local development, such as the local protocol or port.

{
	"dev": {
		"ip": "192.168.1.1",
		"port": 8080,
		"local_protocol": "http",
	},
}
[dev]
ip = "192.168.1.1"
port = 8_080
local_protocol = "http"

Secrets

Secrets are a type of binding that allow you to attach encrypted text values to your Worker.

secrets configuration property

The secrets configuration property lets you declare the secret names your Worker requires in your Wrangler configuration file. Required secrets are validated during local development and deploy, and used as the source of truth for type generation.

{
	"secrets": {
		"required": ["API_KEY", "DB_PASSWORD"],
	},
}
[secrets]
required = [ "API_KEY", "DB_PASSWORD" ]

Type generation

When secrets is defined at any config level, wrangler types generates typed bindings from the names listed in secrets.required and no longer infers secret names from .dev.vars or .env files. This lets you run type generation in environments where those files are not present.

Per-environment secrets are supported. Each named environment produces its own interface, and the aggregated Env type marks secrets that only appear in some environments as optional.

Deploy

When secrets is defined, wrangler deploy and wrangler versions upload validate that all secrets in secrets.required are configured on the Worker before the operation succeeds. If any required secrets are missing, the command fails with an error listing which secrets need to be set.

Local development

Put secrets for use in local development in either a .dev.vars file or a .env file, in the same directory as the Wrangler configuration file.

These files should be formatted using the dotenv syntax. For example:

.dev.vars / .env
SECRET_KEY="value"
API_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"

To set different secrets for each Cloudflare environment, create files named .dev.vars.<environment-name> or .env.<environment-name>.

When you select a Cloudflare environment in your local development, the corresponding environment-specific file will be loaded ahead of the generic .dev.vars (or .env) file.

Module Aliasing

You can configure Wrangler to replace all calls to import a particular package with a module of your choice, by configuring the alias field:

{
	"alias": {
		"foo": "./replacement-module-filepath",
	},
}
[alias]
foo = "./replacement-module-filepath"
replacement-module-filepath.js
export const bar = "baz";

With the configuration above, any calls to import or require() the module foo will be aliased to point to your replacement module:

import { bar } from "foo";

console.log(bar); // returns "baz"

Bundling issues

When Wrangler bundles your Worker, it might fail to resolve dependencies. Setting up an alias for such dependencies is a simple way to fix the issue.

However, before doing so, verify that the package is correctly installed in your project, either as a direct dependency in package.json or as a transitive dependency.

If an alias is the correct solution for your dependency issue, you have several options:

Example: Aliasing dependencies from NPM

You can use module aliasing to provide an implementation of an NPM package that does not work on Workers — even if you only rely on that NPM package indirectly, as a dependency of one of your Worker's dependencies.

For example, some NPM packages depend on node-fetch, a package that provided a polyfill of the fetch() API, before it was built into Node.js.

node-fetch isn't needed in Workers, because the fetch() API is provided by the Workers runtime. And node-fetch doesn't work on Workers, because it relies on currently unsupported Node.js APIs from the http/https modules.

You can alias all imports of node-fetch to instead point directly to the fetch() API that is built into the Workers runtime:

{
	"alias": {
		"node-fetch": "./fetch-polyfill",
	},
}
[alias]
node-fetch = "./fetch-polyfill"
./fetch-polyfill
export default fetch;

Example: Aliasing Node.js APIs

You can use module aliasing to provide your own polyfill implementation of a Node.js API that is not yet available in the Workers runtime.

For example, let's say the NPM package you rely on calls fs.readFile. You can alias the fs module by adding the following to your Worker's Wrangler configuration file:

{
	"alias": {
		"fs": "./fs-polyfill",
	},
}
[alias]
fs = "./fs-polyfill"
./fs-polyfill
export function readFile() {
	// ...
}

In many cases, this allows you to work provide just enough of an API to make a dependency work. You can learn more about Cloudflare Workers' support for Node.js APIs on the Cloudflare Workers Node.js API documentation page.

Source maps

Source maps translate compiled and minified code back to the original code that you wrote. Source maps are combined with the stack trace returned by the JavaScript runtime to present you with a stack trace.

Example:

{
	"upload_source_maps": true,
}
upload_source_maps = true

Workers Sites

Workers Sites allows you to host static websites, or dynamic websites using frameworks like Vue or React, on Workers.

Example:

{
	"site": {
		"bucket": "./public",
		"include": ["upload_dir"],
		"exclude": ["ignore_dir"],
	},
}
[site]
bucket = "./public"
include = [ "upload_dir" ]
exclude = [ "ignore_dir" ]

Proxy support

Corporate networks will often have proxies on their networks and this can sometimes cause connectivity issues. To configure Wrangler with the appropriate proxy details, add the following environmental variables:

To configure this on macOS, add HTTP_PROXY=http://<YOUR_PROXY_HOST>:<YOUR_PROXY_PORT> before your Wrangler commands.

Example:

$ HTTP_PROXY=http://localhost:8080 wrangler dev

If your IT team has configured your computer's proxy settings, be aware that the first non-empty environment variable in this list will be used when Wrangler makes outgoing requests.

For example, if both https_proxy and http_proxy are set, Wrangler will only use https_proxy for outgoing requests.

Source of truth

We recommend treating your Wrangler configuration file as the source of truth for your Worker configuration, and to avoid making changes to your Worker via the Cloudflare dashboard if you are using Wrangler.

If you need to make changes to your Worker from the Cloudflare dashboard, the dashboard will generate a TOML snippet for you to copy into your Wrangler configuration file, which will help ensure your Wrangler configuration file is always up to date.

If you change your environment variables in the Cloudflare dashboard, Wrangler will override them the next time you deploy. If you want to disable this behavior, add keep_vars = true to your Wrangler configuration file.

If you change your routes in the dashboard, Wrangler will override them in the next deploy with the routes you have set in your Wrangler configuration file. To manage routes via the Cloudflare dashboard only, remove any route and routes keys from your Wrangler configuration file. Then add workers_dev = false to your Wrangler configuration file. For more information, refer to Deprecations.

Wrangler will not delete your secrets (encrypted environment variables) unless you run wrangler secret delete <key>.

Generated Wrangler configuration

Some framework tools, or custom pre-build processes, generate a modified Wrangler configuration to be used to deploy the Worker code. In this case, the tool may also create a special .wrangler/deploy/config.json file that redirects Wrangler to use the generated configuration rather than the original, user's configuration.

Wrangler uses this generated configuration only for the following deploy and dev related commands:

When running these commands, Wrangler looks up the directory tree from the current working directory for a file at the path .wrangler/deploy/config.json. This file must contain only a single JSON object of the form:

{ "configPath": "../../path/to/wrangler.jsonc" }

When this config.json file exists, Wrangler will follow the configPath (relative to the .wrangler/deploy/config.json file) to find the generated Wrangler configuration file to load and use in the current command. Wrangler will display messaging to the user to indicate that the configuration has been redirected to a different file than the user's configuration file.

The generated configuration file should not include any environments. This is because such a file, when required, should be created as part of a build step, which should already target a specific environment. These build tools should generate distinct deployment configuration files for different environments.

Custom build tool example

A common example of using a redirected configuration is where a custom build tool, or framework, wants to modify the user's configuration to be used when deploying, by generating a new configuration in a dist directory.

The generated dist/wrangler.jsonc might contain:

{
	"name": "my-worker",
	"main": "./index.js",
	"vars": {
		"MY_VARIABLE": "staging variable"
	}
}

Now, the main property points to the generated code entry-point, no environment is defined, and the MY_VARIABLE variable is resolved to the staging environment value.

And the .wrangler/deploy/config.json contains the path to the generated configuration file:

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