# How to Handle Hot Module Replacement with the Wrangler Dev Server in Next.js

> Learn how to handle hot module replacement with Wrangler dev server in Next.js. Run both servers concurrently for seamless UI hot-reloading and Cloudflare Workers runtime.

- Repository: [Muhammad Arifin/fullstack-next-cloudflare](https://github.com/ifindev/fullstack-next-cloudflare)
- Tags: how-to-guide
- Published: 2026-03-04

---

**To handle HMR with the Wrangler dev server, run the Next.js development server concurrently with Wrangler, allowing Next.js to manage UI hot-reloading while Wrangler provides the Cloudflare Workers runtime.**

When building full-stack applications with the `ifindev/fullstack-next-cloudflare` template, you must navigate a specific architectural constraint: the Wrangler dev server does not support Hot Module Replacement (HMR) for Worker bundles. This article explains how to handle hot module replacement with the Wrangler dev server by leveraging a dual-server workflow that preserves instant UI updates while maintaining access to Cloudflare bindings like D1 and R2.

## Why the Wrangler Dev Server Lacks HMR

Cloudflare Workers run in a specialized V8 isolate environment that differs significantly from Node.js. When you start the Wrangler dev server using `wrangler dev`, it compiles your Worker into a bundle and launches a local Miniflare runtime to simulate the Cloudflare Edge environment. Because this runtime loads a compiled bundle rather than raw source modules, it cannot swap individual modules without a full process restart. According to the repository's source code, this limitation is intrinsic to the Worker architecture—the Wrangler process serves the compiled output from [`.open-next/worker.js`](https://github.com/ifindev/fullstack-next-cloudflare/blob/main/.open-next/worker.js) as specified in `wrangler.jsonc`, and no mechanism exists within `wrangler dev` to hot-swap this bundle.

## The Dual-Server Development Workflow

The recommended approach to handle hot module replacement with the Wrangler dev server involves running two separate processes simultaneously. The [`package.json`](https://github.com/ifindev/fullstack-next-cloudflare/blob/main/package.json) in the repository exposes distinct scripts for each responsibility:

```json
"scripts": {
  "dev": "next dev",
  "wrangler:dev": "npx wrangler dev",
  "dev:cf": "npx @opennextjs/cloudflare build && wrangler dev",
  "dev:remote": "npx @opennextjs/cloudflare build && wrangler dev --remote"
}

```

### Starting the Wrangler Dev Server

First, launch the Cloudflare Workers runtime to access local bindings. In `ifindev/fullstack-next-cloudflare`, execute:

```bash
pnpm run wrangler:dev

```

This command reads the configuration from `wrangler.jsonc` and starts the local runtime on `http://localhost:8787`. This server provides access to D1 databases, R2 buckets, and AI bindings, but **does not support HMR**. Any changes to API routes or Worker-specific code require stopping and restarting this process.

### Starting the Next.js Dev Server

In a separate terminal, start the Next.js development server:

```bash
pnpm dev

```

This initiates the standard Next.js dev server with full HMR support. As implemented in [`next.config.ts`](https://github.com/ifindev/fullstack-next-cloudflare/blob/main/next.config.ts), the template calls `initOpenNextCloudflareForDev()` when `NODE_ENV` equals `"development"`:

```typescript
import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";

const nextConfig = {
  // Your Next.js configuration
};

if (process.env.NODE_ENV === "development") {
  initOpenNextCloudflareForDev();
}

export default nextConfig;

```

This function injects the same environment variables that Wrangler provides, allowing the Next.js server to communicate with local D1 or R2 instances directly while preserving React's fast refresh capabilities.

## Configuring Next.js for Cloudflare Bindings

The `initOpenNextCloudflareForDev()` function is critical for bridging the two environments. By invoking this helper from `@opennextjs/cloudflare` inside [`next.config.ts`](https://github.com/ifindev/fullstack-next-cloudflare/blob/main/next.config.ts), you enable the Next.js dev server to recognize Cloudflare-specific bindings during development. This means your frontend code can execute database queries against the local D1 instance managed by Wrangler without deploying to the Edge. Note that this configuration only applies to the development environment; production builds use the standard Worker bundle output.

## Running Both Servers with a Single Command

If you prefer not to manage multiple terminal windows, you can automate the dual-server setup using `concurrently`. Add the following to your [`package.json`](https://github.com/ifindev/fullstack-next-cloudflare/blob/main/package.json):

```json
"scripts": {
  "dev:all": "concurrently \"pnpm wrangler:dev\" \"pnpm dev\""
}

```

Then start both processes with:

```bash
pnpm run dev:all

```

**Important:** While this consolidates the startup process, the Wrangler dev server still requires a manual restart when you modify Worker code. HMR continues to function only for the Next.js side of the application.

## Understanding HMR Boundaries

To develop efficiently, distinguish between what triggers a hot reload versus what requires a full restart:

- **Instant HMR (Next.js server):** React components in `src/app` or `src/components`, CSS modules, client-side hooks, and page layouts update immediately in the browser.
- **Manual restart required (Wrangler server):** API route handlers under `src/app/api`, Cloudflare binding configurations in `wrangler.jsonc`, environment variables, and any code that runs inside the Worker isolate.

When you modify a UI component, the Next.js server injects the updated module without refreshing the page. When you change an API route that uses the D1 database, you must stop and restart the `wrangler:dev` process to rebuild the Worker bundle.

## Summary

- **No native HMR:** The Wrangler dev server cannot hot-reload Worker bundles because it serves compiled JavaScript in a V8 isolate runtime.
- **Dual-server solution:** Run `pnpm wrangler:dev` for the Cloudflare runtime and `pnpm dev` for Next.js with HMR.
- **Configuration bridge:** The `initOpenNextCloudflareForDev()` function in [`next.config.ts`](https://github.com/ifindev/fullstack-next-cloudflare/blob/main/next.config.ts) enables the Next.js server to access local Cloudflare bindings during development.
- **Restart requirements:** API route changes require restarting the Wrangler process, while UI updates reflect instantly via Next.js HMR.
- **Automation option:** Use `concurrently` to launch both servers with a single command, though Wrangler still restarts manually when needed.

## Frequently Asked Questions

### Does the Wrangler dev server support HMR for Cloudflare Workers?

No. The Wrangler dev server serves a compiled Worker bundle and cannot hot-swap individual modules. It requires a full restart to load code changes, which is a limitation of the Cloudflare Workers runtime architecture as implemented in the local Miniflare environment.

### Why do I need to run two servers for local development?

You need two servers because each handles a distinct responsibility. The Wrangler dev server provides the Cloudflare Workers runtime with access to D1, R2, AI, and other Edge bindings, while the Next.js dev server handles React compilation and provides HMR for the frontend. Running both concurrently allows you to develop with instant UI updates while testing against real Cloudflare APIs locally.

### How do I access Cloudflare D1 or R2 during development with HMR?

Configure [`next.config.ts`](https://github.com/ifindev/fullstack-next-cloudflare/blob/main/next.config.ts) to call `initOpenNextCloudflareForDev()` when `NODE_ENV` is `"development"`. This function bridges the Next.js dev server with the Wrangler runtime, allowing your React code to query local D1 databases or access R2 buckets directly while maintaining HMR for UI components.

### Can I use a single command to start both Wrangler and Next.js dev servers?

Yes. Install the `concurrently` package and create a compound script in [`package.json`](https://github.com/ifindev/fullstack-next-cloudflare/blob/main/package.json) such as `"dev:all": "concurrently \"pnpm wrangler:dev\" \"pnpm dev\""`. This starts both processes simultaneously, though you must still manually restart the Wrangler process when modifying Worker-specific code, as HMR remains unavailable for the Cloudflare runtime.