How does hot reload work for a Flutter web app in Flutter 3.47, and how does it differ from mobile?
answer
- default on since 3.35
- no Dart VM in the browser
- DDC JavaScript modules
- not for --wasm runs
- --no-web-experimental-hot-reload opt-out
basics
~20 sSince Flutter 3.35 hot reload is on by default for web debug builds, alongside hot restart. It loads updated DDC-compiled JavaScript into the page instead of a Dart VM, keeps state, and does not apply to Wasm or release builds.
solid answer
~40 sBefore Flutter 3.35, pressing `r` on the web performed a hot restart; since 3.35 real hot reload is on by default. Debug web builds are compiled to JavaScript by the Dart development compiler, and hot reload loads updated modules into the running page, rebuilding widgets with state kept. The rules about what reloads are the same as on mobile: `main()`, existing `initState()` calls and static initializers are not rerun. Hot restart restarts the app without a full page refresh, and a full restart also restarts the compiler. It is a debug-only feature and not available for `--wasm` runs; `--no-web-experimental-hot-reload` is a deprecated, temporary opt-out.
code
bash · 8 lines# Debug run in Chrome: hot reload (r) and hot restart (R) both work
flutter run -d chrome
# Temporary opt-out if web hot reload misbehaves (deprecated flag)
flutter run -d chrome --no-web-experimental-hot-reload
# WebAssembly build: no hot reload
flutter run -d chrome --wasmgo deeper
Know that current Flutter web supports hot reload by default in debug runs, not just hot restart.
Explain that web debug builds use the development compiler and JavaScript modules instead of a VM, and what that means for Wasm runs.
Diagnose web reload problems, from Wasm runs to web-server sessions without a debugger, and know the temporary opt-out and where to report bugs.
Factor the web dev loop into platform decisions: a team building mainly for the web now gets the same iteration speed as on mobile.
## Hot reload on the web: the short version For years, pressing `r` on a Flutter web app performed a **hot restart**: the app restarted in the page and lost its state. Since **Flutter 3.35**, **hot reload is enabled by default on the web** as well, alongside hot restart. In Flutter 3.47 it behaves, from the developer's seat, much like on mobile: edit Dart code, reload, and the widget tree rebuilds with state kept. ## How it differs from mobile underneath On Android and iOS, debug builds run a Dart VM on the device and hot reload sends it compiled **kernel files**. On the web there is no Dart VM in the browser. Debug web builds are compiled to JavaScript by the **Dart development compiler (DDC)**, and hot reload works by loading updated JavaScript modules into the running page. Consequences: | | Mobile (Dart VM) | Web (DDC debug build) | |---|---|---| | Where new code goes | Into the device's Dart VM | Into the browser page | | Where rejections happen | In the VM, when patching | Mostly at compile time | | Hot restart | Restarts the Dart app | Restarts the app without a full page refresh | | Full restart | Rebuilds native code | Also restarts the development compiler | | Default since | Always, in debug | Flutter 3.35 | The same rules about **what** reloads apply on both: `main()` and existing `initState()` calls are not rerun, global and static fields keep their values, and enum or generic shape changes need a hot restart. ## Where web hot reload does not apply - **Release and profile builds.** Hot reload and hot restart are debug-mode features on every platform. - **WebAssembly runs.** `flutter run -d chrome --wasm` builds a Wasm app; the tool connects its debug service only to non-Wasm debug web builds, so hot reload is a feature of the DDC JavaScript debug build. - **The `web-server` device** without a debug connection. The tool treats it as debuggable only with `--start-paused` or a debug-service WebSocket connection; without one, the run session has no channel through which to reload the page. ## Turning it off If web hot reload misbehaves, the docs show a temporary opt-out flag for `flutter run`: ```bash flutter run -d chrome --no-web-experimental-hot-reload ``` In Flutter 3.47 the tool marks `--web-experimental-hot-reload` as **deprecated and to be removed in a future release**, and it defaults to on, so treat the opt-out as a stop-gap and report the problem. Issues go to the Dart SDK repository's web hot reload tracker, because the compiler lives there. ## Practical tips for web development 1. Run in Chrome (`-d chrome`), or the `edge` device on Windows, so the tool manages the browser and its debug connection. 2. Expect browser state outside Dart to persist: `localStorage`, cookies and the URL survive a hot restart because the page is not reloaded. 3. A manual browser refresh reloads the page and starts the Dart app from scratch, so treat it like a restart, not a reload. 4. Keep an eye on the console for `Hot reload failed:` followed by reasons, which the web runner prints when the development compiler reports a problem. ## Why interviewers ask The question checks that a candidate's knowledge is current. Answers such as "web only has hot restart" were true before 3.35 and are a clear sign of stale experience, as is mentioning the removed HTML renderer in the same breath.
- Why does localStorage survive a hot restart of a Flutter web app?On the web a hot restart restarts the Dart app without a full page refresh, so browser-held state such as `localStorage`, cookies and the current URL is untouched. Only Dart state, meaning widgets, `State` objects and statics, starts fresh.
saying these in an interview costs you the question
- Flutter web only supports hot restart, never hot reload.
- Web hot reload needs a Dart VM running inside the browser.
- Hot reload works the same in --wasm runs as in JavaScript debug builds.
- Web hot reload reruns main() because the page reloads.