Skip to content

Commit 49c069b

Browse files
committed
adds draft docs for connecting to remote resources during local dev (hybrid dev)
1 parent 953647a commit 49c069b

File tree

4 files changed

+319
-81
lines changed

4 files changed

+319
-81
lines changed

src/content/docs/workers/local-development/index.mdx

Lines changed: 275 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,45 +7,294 @@ head: []
77
description: Develop your Workers locally.
88
---
99

10-
import { Details, LinkCard, Render, PackageManagers } from "~/components";
10+
import {
11+
Details,
12+
LinkCard,
13+
Render,
14+
PackageManagers,
15+
WranglerConfig,
16+
Aside,
17+
} from "~/components";
1118

12-
When building projects on Cloudflare Workers, you have two options for local development:
19+
Local development allows you to build, run, and test your Worker code on your own machine before deploying it to Cloudflare's network. This is made possible through [Miniflare](/workers/testing/miniflare/), a simulator that executes your Worker code using the same runtime used in production, [`workerd`](https://github.com/cloudflare/workerd). By default, your Worker's bindings connect to locally simulated resources, but can be configured to interact with the real, production resource.
1320

14-
- [**Wrangler**](/workers/wrangler/), using the built-in [`wrangler dev`](/workers/wrangler/commands/#dev) command.
15-
- [Vite](https://vite.dev/), using the [**Cloudflare Vite plugin**](/workers/vite-plugin/).
21+
## Start a development server
1622

17-
Both Wrangler and the Vite plugin use [Miniflare](/workers/testing/miniflare/) to provide an accurate **local** simulation of the Cloudflare Workers runtime, ([`workerd`](https://github.com/cloudflare/workerd)). If you need to [develop with **remote resources**](/workers/local-development/remote-data/), Wrangler is the only option, and provides remote development via the `wrangler dev --remote` command.
23+
You can start a local development server using:
1824

19-
## Choosing between Wrangler or Vite
25+
1. Our official CLI [**Wrangler**](/workers/wrangler/), using the built-in [`wrangler dev`](/workers/wrangler/commands/#dev) command.
2026

21-
Deciding between Wrangler and the Cloudflare Vite plugin depends on your project's focus and development workflow. Here are some quick guidelines to help you choose:
27+
<PackageManagers type="exec" pkg="wrangler" args="dev" />
2228

23-
### When to use Wrangler
29+
2. [**Vite**](https://vite.dev/), using the [**Cloudflare Vite plugin**](/workers/vite-plugin/).
2430

25-
- **Backend & Workers-focused:**
26-
If you're primarily building APIs, serverless functions, or background tasks, use Wrangler.
31+
<PackageManagers type="exec" pkg="vite" args="dev" />
2732

28-
- **Remote development:**
29-
If your project needs the ability to develop and test using production resources and data on Cloudflare's network, use Wrangler's `--remote` flag.
33+
Both Wrangler and the Cloudflare Vite plugin are clients to Miniflare, and fully supported by Cloudflare. For guidance on choosing when to use Wrangler versus Vite, see our guide [Choosing between Wrangler & Vite](/workers/local-development/wrangler-vs-vite/).
3034

31-
- **Simple frontends:**
32-
If you have minimal frontend requirements and don’t need hot reloading or advanced bundling, Wrangler may be sufficient.
35+
- [Get started with Wrangler](/workers/wrangler/install-and-update/)
36+
- [Get started with the Cloudflare Vite plugin](/workers/vite-plugin/get-started/)
3337

34-
### When to use the Cloudflare Vite Plugin
38+
### Default Behavior (Fully local)
3539

36-
Use the [Vite plugin](/workers/vite-plugin/) for:
40+
By default, running `wrangler dev` / `vite dev` (when using the [Vite plugin](/workers/vite-plugin/get-started/)) means that:
3741

38-
- **Frontend-centric development:**
39-
If you already use Vite with modern frontend frameworks like React, Vue, Svelte, or Solid, the Vite plugin integrates into your development workflow.
42+
- Your Worker code runs on your local machine.
43+
- All resources your Worker is bound to in your [Wrangler configuration](/workers/wrangler/configuration/) are simulated locally.
4044

41-
- **React Router v7:**
42-
If you are using [React Router v7](https://reactrouter.com/) (the successor to Remix), it is officially supported by the Vite plugin as a full-stack SSR framework.
45+
### Bindings during local development
4346

44-
- **Rapid iteration (HMR):**
45-
If you need near-instant updates in the browser, the Vite plugin provides [Hot Module Replacement (HMR)](https://vite.dev/guide/features.html#hot-module-replacement) during local development.
47+
[Bindings](/workers/runtime-apis/bindings/) are interfaces that allow your Worker to interact with various Cloudflare resources (like [KV namespaces](/kv), [R2 buckets](/r2), [D1 databases](/d1), [Queues](/queues/), [Durable Objects](/durable-objects/), etc). In your Worker code, these are accessed via the `env` object (such as `env.MY_KV`).
4648

47-
- **Advanced optimizations:**
48-
If you require more advanced optimizations (code splitting, efficient bundling, CSS handling, build time transformations, etc.), Vite is a strong fit.
49+
During local development, your Worker code interacts with these bindings using the exact same API calls (such as `env.MY_KV.put()`) as it would in a deployed environment. Miniflare intercepts these calls and directs them to the locally simulated resource. These local resources are initially empty, but you can populate them with data, as documented in [Adding local data](/workers/local-development/local-data/).
4950

50-
- **Greater flexibility:**
51-
Due to Vite's advanced configuration options and large ecosystem of plugins, there is more flexibility to customize your development experience and build output.
51+
- By default, bindings connect to **local resource simulations** (except for [AI bindings](/workers-ai/configuration/bindings/), as AI models always run remotely).
52+
- You can override this default behavior and **connect to the remote resource**, on a per-binding basis. This lets you connect to real, production resources while still running your Worker code locally.
53+
54+
## Connect to remote resources (Hybrid)
55+
56+
There are times when you might want to connect to the real, remote resource during local development _instead_ of the locally simulated resource. You can configure this on a per-binding basis, by setting `remote: true` in the binding definition.
57+
58+
**For example:**
59+
60+
<WranglerConfig>
61+
62+
```jsonc title="wrangler.jsonc"
63+
{
64+
"name": "my-worker",
65+
"compatibility_date": "2025-06-01",
66+
67+
"browser": {
68+
"binding": "MY_BROWSER",
69+
"remote": true,
70+
},
71+
72+
"queues": {
73+
"producers": [
74+
{
75+
"queue": "queues-web-crawler",
76+
"binding": "queues_web_crawler",
77+
"remote": false, // Default value, but here for illustration
78+
},
79+
],
80+
"consumers": [
81+
{
82+
"queue": "queues-web-crawler",
83+
"max_batch_size": 5,
84+
"max_batch_timeout": 30,
85+
"max_retries": 3,
86+
"dead_letter_queue": "web-crawler-dlq",
87+
"remote": false, // Default value, but here for illustration
88+
},
89+
],
90+
},
91+
92+
"r2_buckets": [
93+
{
94+
"bucket_name": "screenshots-bucket",
95+
"binding": "screenshots_bucket",
96+
"preview_bucket_name": "preview-screenshots-bucket",
97+
"remote": true,
98+
},
99+
],
100+
}
101+
```
102+
103+
</WranglerConfig>
104+
105+
In the above example, you’re able to more realistically test out and trust that any [Browser Rendering](/browser-rendering/) interactions work as intended, as well as validate the end results of the screenshots in R2 – while leaving room to rapidly iterate on the actual logic within your Worker and queues.
106+
107+
<Aside type="tip">
108+
109+
This hybrid approach to local development is supported both in Wrangler and the Cloudflare Vite plugin.
110+
111+
</Aside>
112+
113+
### How it works
114+
115+
When you run you local dev command and a binding definition includes `remote: true`, the following takes place:
116+
117+
- Your Worker's code continues to run on your machine within `workerd`, managed by Miniflare (whether initiated by Wrangler or Vite).
118+
- For all bindings marked with `remote: true`, Miniflare routes its operations (such as `env.MY_KV.put()`) to the deployed resource. This connection is facilitated through a secure proxy mechanism provisioned on Cloudflare's network.
119+
- All other bindings not explicitly configured with `remote: true` continue to use their default local simulations.
120+
- Your Worker code remains unchanged, regardless of whether the bindings is fully local or connected remotely.
121+
122+
### Targeting Preview vs. Production resources
123+
124+
To protect production data, you can create and specify preview resources in your [Wrangler configuration](/workers/wrangler/configuration/), such as:
125+
126+
- [Preview namespaces for KV stores](/workers/wrangler/configuration/#kv-namespaces):`preview_id`.
127+
- [Preview buckets for R2 storage](/workers/wrangler/configuration/#r2-buckets): `preview_bucket_name`.
128+
- [Preview database IDs for D1](/workers/wrangler/configuration/#d1-databases): `preview_database_id`
129+
130+
If preview configuration is present for a binding, setting `remote: true` will make your local session connect to that designated remote preview resource.
131+
If no preview configuration is specified, `remote: true` will connect to the main remote production resource.
132+
133+
**For example:**
134+
135+
<WranglerConfig>
136+
137+
```jsonc title="wrangler.jsonc"
138+
{
139+
"name": "my-worker",
140+
"compatibility_date": "2025-06-01",
141+
142+
"r2_buckets": [
143+
{
144+
"bucket_name": "screenshots-bucket",
145+
"binding": "screenshots_bucket",
146+
"preview_bucket_name": "preview-screenshots-bucket",
147+
"remote": true,
148+
},
149+
],
150+
}
151+
```
152+
153+
</WranglerConfig>
154+
155+
Running your local dev command (`wrangler dev` / `vite dev`) with the above configuration means that:
156+
157+
- Your Worker code runs locally
158+
- All calls made to `env.screenshots_bucket` will use the `preview-screenshots-bucket` resource, rather than the production `screenshots-bucket`.
159+
160+
### Recommended remote bindings
161+
162+
We recommend configuring specific bindings to connect to their remote counterparts. These services often rely on Cloudflare's network infrastructure or have complex backends that are not fully simulated locally.
163+
164+
The following bindings are recommended to have `remote: true` in your Wrangler configuration:
165+
166+
- [**Browser Rendering**](/workers/wrangler/configuration/#browser-rendering): To interact with a real headless browser for rendering.
167+
168+
- [**Workers AI**](/workers/wrangler/configuration/#workers-ai): To utilize actual AI models deployed on Cloudflare's network for inference.
169+
170+
- [**Vectorize**](/workers/wrangler/configuration/#vectorize-indexes): To connect to your production Vectorize indexes for accurate vector search and similarity operations.
171+
172+
- **Service bindings to [mTLS-enabled services](/workers/wrangler/configuration/#mtls-certificates)**: If you have a service binding that points to a deployed Worker or service that requires mTLS authentication from its clients, setting `remote: true` for that service binding is recommended for realistic end-to-end testing. Your Worker would then use an `mtls_certificates` binding to make the call.
173+
174+
#### Behavior and configuration:
175+
176+
- If `remote: true` is not specified for Browser Rendering, Vectorize, or for a service binding that is intended to call an mTLS-protected remote service, Cloudflare will issue a warning. This prompts you to consider enabling it for a more production-like testing experience.
177+
- For Workers AI, if the `ai.remote` property is set to `false`, Cloudflare will produce an error. If the property is omitted, Cloudflare will connect to the remote resource and issue a warning to add the property to configuration.
178+
179+
<WranglerConfig>
180+
```jsonc title="wrangler.jsonc"
181+
{
182+
"name": "my-worker",
183+
"compatibility_date": "2025-06-01",
184+
// ... other configurations ...
185+
"browser": {
186+
"binding": "MY_BROWSER",
187+
"remote": true // Recommended
188+
},
189+
"vectorize": [
190+
{
191+
"binding": "MY_VECTORIZE_INDEX",
192+
"index_name": "my-prod-index",
193+
"remote": true // Recommended
194+
}
195+
],
196+
"services": [
197+
{
198+
"binding": "API_SERVICE_REQUIRING_MTLS", // A service this worker calls
199+
"service": "deployed-api-worker-expecting-mtls", // This target service expects mTLS
200+
"remote": true // Recommended
201+
}
202+
],
203+
"ai": {
204+
"binding": "AI", // Access as env.AI
205+
"remote": true // Required; setting to false or omitting will error
206+
},
207+
"mtls_certificates": [ // Defines how this worker can present a client certificate
208+
{
209+
"binding": "MY_CLIENT_CERT_FETCHER", // Access as env.MY_CLIENT_CERT_FETCHER
210+
"certificate_id": "<YOUR_UPLOADED_CERT_ID>"
211+
// Note: 'remote: true' is NOT applicable here. This binding provides a
212+
// an object that has a `.fetch()` method.
213+
}
214+
]
215+
// Note: For other services like KV, R2, D1, Queues, 'remote: true' is optional
216+
}
217+
```
218+
</WranglerConfig>
219+
220+
### Limitations - Unsupported remote bindings
221+
222+
While the hybrid approach allows many bindings to connect to remote resources, certain bindings are not supported for remote connections during local development (`remote: true`). These will always use local simulations or local values.
223+
224+
If `remote: true` is specified in Wrangler configuration for any of the following unsupported binding types, Cloudflare will issue an error.
225+
226+
- [**Durable Objects**](/workers/wrangler/configuration/#durable-objects): Durable Objects have synchronous operational aspects in their API. The current hybrid development proxy mechanism primarily supports asynchronous operations. Enabling remote connections for Durable Objects may be supported in the future, but currently will always run locally.
227+
228+
- [**Environment Variables (`vars`)**](/workers/wrangler/configuration/#environment-variables): Environment variables are intended to be distinct between local development and deployed environments (`production`, `preview`). They are easily configurable locally (such as in a `.dev.vars` file or directly in Wrangler configuration.
229+
230+
- [**Secrets**](/workers/wrangler/configuration/#secrets): Like environment variables, secrets are expected to have different values in local development versus deployed environments for security reasons. Use `.dev.vars` for local secret management.
231+
232+
- **[Assets (Static Assets)](//workers/wrangler/configuration/#assets)**: Static assets are always served from your local disk during development for speed and direct feedback on changes.
233+
234+
- [**Version Metadata**](/workers/runtime-apis/bindings/version-metadata/): Since your Worker code is running locally, version metadata (like commit hash, version tags) associated with a specific deployed version is not applicable or accurate.
235+
236+
- [**Analytics Engine**](/analytics/analytics-engine/): Local development sessions typically don't contribute data directly to production Analytics Engine.
237+
238+
- [**Hyperdrive**](/workers/wrangler/configuration/#hyperdrive): This is being actively worked on, but is currently unsupported.
239+
- [**Rate Limiting**](/workers/runtime-apis/bindings/rate-limit/#configuration): Local development sessions typically should not share or affect rate limits of your deployed Workers. Rate limiting logic should be tested against local simulations.
240+
241+
<Aside type="tip">
242+
243+
If you have use-cases for connecting to any of the remote resources above, please [open a feature request](/https://github.com/cloudflare/workers-sdk/issues) in our [`workers-sdk` repository](https://github.com/cloudflare/workers-sdk).
244+
245+
</Aside>
246+
247+
### Important Considerations
248+
249+
- **Data modification**: Operations (writes, deletes, updates) on bindings connected remotely will affect your actual data in the targeted Cloudflare resource (be it preview or production).
250+
251+
- **Billing**: Interactions with remote Cloudflare services through these connections will incur standard operational costs for those services (such as KV operations, R2 storage/operations, AI requests, D1 usage).
252+
253+
- **Network latency**: Expect network latency for operations on these remotely connected bindings, as they involve communication over the internet.
254+
255+
- **Environment Variables & Secrets**: Standard environment variables (from [vars]) and Secrets always use their locally defined values during local development. The `remote: true` flag does not apply to them.
256+
257+
### API
258+
259+
TO-DO
260+
261+
## Remote development
262+
263+
Separate from Miniflare-powered local development, Wrangler also offers a fully remote development mode via [`wrangler dev --remote`](/workers/wrangler/commands/#dev). Remote development is [**not** supported in the Vite plugin](/workers/local-development/wrangler-vs-vite/).
264+
265+
<PackageManagers type="exec" pkg="wrangler" args="dev --remote" />
266+
267+
### How It Works
268+
269+
The `wrangler dev --remote` command creates a temporary preview deployment on Cloudflare's infrastructure.
270+
271+
When you run `wrangler dev --remote`:
272+
273+
- All of your code is uploaded to a temporary preview environment on Cloudflare's infrastructure.
274+
- Changes to your code are automatically uploaded as you save.
275+
- All requests and execution happen on Cloudflare's global network.
276+
- The preview automatically terminates when you exit the command.
277+
278+
### When to use Remote development
279+
280+
- For most development tasks, the most efficient and productive experience will be local development along with [connections to remote resources](/workers/local-development/#connect-to-remote-resources-hybrid).
281+
- You may want to use `wrangler dev --remote` for testing features or behaviors that are highly specific to Cloudflare's network and cannot be adequately simulated locally or tested via hybrid connections.
282+
283+
### Considerations
284+
285+
- Iteration is significantly slower than local development due to the upload/deployment step for each change.
286+
287+
### Isolating from Production
288+
289+
To protect production data, you can specify preview resources in your [Wrangler configuration](/workers/wrangler/configuration/), such as:
290+
291+
- [Preview namespaces for KV stores](/workers/wrangler/configuration/#kv-namespaces):`preview_id`.
292+
- This option is **required** when using `wrangler dev --remote`.
293+
- [Preview buckets for R2 storage](/workers/wrangler/configuration/#r2-buckets): `preview_bucket_name`.
294+
- [Preview database IDs for D1](/workers/wrangler/configuration/#d1-databases): `preview_database_id`
295+
296+
This separation ensures your development activities don't impact production data while still providing a realistic testing environment.
297+
298+
### Limitations
299+
300+
- When you run a remote development session using the `--remote` flag, a limit of 50 [routes](/workers/configuration/routing/routes/) per zone is enforced. Learn more in[ Workers platform limits](/workers/platform/limits/#number-of-routes-per-zone-when-using-wrangler-dev---remote).

src/content/docs/workers/local-development/local-data.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
---
22
pcx_content_type: navigation
3-
title: Local data
3+
title: Adding local data
44
sidebar:
55
order: 2
66
head: []
7-
description: Working with data during local development
7+
description: Populating local resources with data
88
---
99

1010
import {

0 commit comments

Comments
 (0)