Mobile Development 10 min read

Understanding Flutter Hot Reload: Mechanism and Implementation

Flutter’s sub‑second hot‑reload works by scanning changed Dart files, generating incremental kernel (.dill) files, sending them to the running Dart VM via RPC, triggering the VM’s reload routine, and finally invoking the framework’s reassemble sequence to rebuild the widget tree, all enabled by JIT compilation during development.

Xianyu Technology
Xianyu Technology
Xianyu Technology
Understanding Flutter Hot Reload: Mechanism and Implementation

1. Introduction

Since Xianyu introduced Flutter, more and more business scenarios are built with it. Flutter’s sub‑second hot‑reload is a powerful tool that lets developers modify UI, add features, or fix bugs without restarting the app, instantly seeing the changes.

How does hot‑reload actually work?

This article walks you through the inner workings of Hot Reload step by step.

2. Source Code Analysis

2.1 FlutterTools Debugging

To understand how Hot Reload runs, we first need to know how to debug flutter_tools.

We create a simple Flutter project named fluttertest as an example.

Open flutter_tools in Android Studio ( /flutter/packages/flutter_tools) and set a breakpoint at HotRunner.restart().

Add a new Debug Configuration, set the working directory to the fluttertest project path.

Trigger the flutter_tools debug button, let the app start, then make a small change in the fluttertest code.

In the flutter_tools Debug Console type r to start hot‑reload.

Breakpoint hit successfully!

2.2 HotReload Basic Process

When we invoke Hot Reload (either by typing r in the console or clicking the lightning icon), Flutter ultimately calls HotRunner.restart(fullRestart: false) inside flutter_tools.

The restart() method invokes _reloadSources(pause: pauseAfterRestart), which is the core of Hot Reload.

(/flutter/packages/flutter_tools/lib/src/run/hot.dart)

Future<OperationResult> _reloadSources({bool pause = false})

The _reloadSources method performs three main steps:

It calls _updateDevFS() to scan all project files, generate kernel files (named app.dill.incremental.dill ), and send them to the Dart VM via an HTTP port.

The generated .dill file path is passed to the RPC interface _reloadSources for resource loading.

After the VM confirms a successful reload, the Flutter engine resets the UI thread, triggers a widget‑tree rebuild and repaint through RPC.

Understanding this flow requires knowledge of Flutter’s compilation modes.

Flutter uses two compilation modes: AOT (Ahead‑Of‑Time) and JIT (Just‑In‑Time). JIT compiles code at runtime, which is slower but allows hot reload. AOT compiles ahead of time for release builds, yielding faster execution.

During development, Flutter uses the Kernel Snapshot mode (JIT). It generates kernel files from Dart source, which the VM interprets at runtime. In release, iOS uses AOT, while Android uses a “Core JIT” that loads pre‑compiled binaries before the VM starts.

Thus, Hot Reload scans the project, converts changed Dart files into kernel files, sends them to the running Dart VM, which replaces the resources and notifies the Flutter framework to rebuild the widget tree.

2.3 Incremental Code Scanning

After the app starts, the build directory contains an app.dill file. Using the strings command reveals that it contains the full compiled Dart code.

When Hot Reload runs, _updateDevFS() creates app.dill.incremental.dill that only includes the changed files.

On the device, the corresponding file appears as kernel_blob.bin under /data/data/com.loommo.fluttertest/app/flutter/flutter_assets. The incremental .dill is sent to the VM via RPC, where the Dart VM’s IsolateReloadContext::Reload method performs the incremental compilation and replaces the old code.

void IsolateReloadContext::Reload(bool force_reload, const char* root_script_url, const char* packages_url_)

After the reload, the Flutter framework triggers a widget‑tree rebuild.

2.4 WidgetsTree Rebuild

The framework registers a Dart VM service named reassemble. When this service is invoked, it starts a cascade of calls:

BindingBase.reassembleApplication → WidgetsBinding.performReassemble → BuildOwner.reassemble → Element.reassemble

(/flutter/packages/flutter/lib/src/foundation/binding.dart) Future<Null> reassembleApplication() This sequence forces the root widget to rebuild, causing the UI to reflect the latest code changes.

3. Conclusion

Flutter’s sub‑second hot reload distinguishes it from traditional native development. Understanding its internals helps developers work more efficiently and provides a foundation for future dynamic‑code solutions.

4. References

Dart VM Service Protocol – https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#rpcs-requests-and-responses

Deep Dive into Flutter Compilation and Optimization

Using Hot Reload – https://flutter.io/hot-reload/

Source code referenced in this article

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

DARTFlutterMobile Developmenthot-reload
Xianyu Technology
Written by

Xianyu Technology

Official account of the Xianyu technology team

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.